蓝山帝景
1.NumPy中形状的含义你写,“我知道字面上是数字列表和列表,其中所有的列表只包含一个数字”,但这是一个有点无助的方式来思考它。考虑NumPy数组的最佳方法是,它们由两个部分组成,数据缓冲器它只是一个原始元素块,而视点描述如何解释数据缓冲区。例如,如果我们创建一个由12个整数组成的数组:>>> a = numpy.arange(12)>>> a
array([ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11])然后a由一个数据缓冲区组成,如下所示:┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘以及描述如何解释数据的视图:>>> a.flags
C_CONTIGUOUS : True
F_CONTIGUOUS : True
OWNDATA : True
WRITEABLE : True
ALIGNED : True
UPDATEIFCOPY : False>>> a.dtype
dtype('int64')>>> a.itemsize8>>> a.strides(8,)>>> a.shape(12,)在这里形形 (12,)表示数组由一个从0到11的索引。i,数组a看起来是这样的:i= 0 1 2 3 4 5 6 7 8 9 10 11┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘如果我们重塑数组,这不会改变数据缓冲区。相反,它创建了一个新视图,该视图描述了解释数据的不同方法。因此,在此之后:>>> b = a.reshape((3, 4))阵列b具有与a,但现在它的索引是二指数分别从0到2和0到3。如果我们给这两个指数贴上标签i和j,数组b看起来是这样的:i= 0 0 0 0 1 1 1 1 2 2 2 2j= 0 1 2 3 0 1 2 3 0 1 2 3┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘这意味着:>>> b[2,1]9您可以看到,第二个索引变化很快,而第一个索引变化缓慢。如果您希望采用相反的方法,则可以指定order参数:>>> c = a.reshape((3, 4), order='F')它会产生一个像这样索引的数组:i= 0 1 2 0 1 2 0 1 2 0 1 2j= 0 0 0 1 1 1 2 2 2 3 3 3┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘这意味着:>>> c[2,1]5现在应该清楚,数组具有一个或多个尺寸为1的形状意味着什么。>>> d = a.reshape((12, 1))阵列d由两个索引,第一个索引从0到11个,第二个索引总是0:i= 0 1 2 3 4 5 6 7 8 9 10 11j= 0 0 0 0 0 0 0 0 0 0 0 0┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘因此:>>> d[10,0]10长度1的维度是“免费的”(从某种意义上说),所以没有什么能阻止你进城:>>> e = a.reshape((1, 2, 1, 6, 1))给出一个像这样索引的数组:i= 0 0 0 0 0 0 0 0 0 0 0 0j= 0 0 0 0 0 0 1 1 1 1 1 1k= 0 0 0 0 0 0 0 0 0 0 0 0l= 0 1 2 3 4 5 0 1 2 3 4 5m= 0 0 0 0 0 0 0 0 0 0 0 0┌────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┬────┐│ 0 │ 1 │ 2 │ 3 │ 4 │ 5 │ 6 │ 7 │ 8 │ 9 │ 10 │ 11 │└────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┴────┘因此:>>> e[0,1,0,0,0]6见NumPy内部文档有关如何实现数组的更多详细信息。2.怎么办?自numpy.reshape只要创建一个新视图,您就不应该害怕在必要时使用它。当您想以不同的方式索引数组时,它是正确的工具。然而,在长时间的计算中,通常可以首先安排构造具有“正确”形状的数组,从而最小化整形和转置的数量。但是,没有看到导致需要重塑的实际背景,很难说应该改变什么。你问题中的例子是:numpy.dot(M[:,0], numpy.ones((1, R)))但这是不现实的。首先,这个短语:M[:,0].sum()计算结果更简单。第二,列0真的有什么特别之处吗?也许你真正需要的是:M.sum(axis=0)
富国沪深
这个形状是一个元组。如果只有一维,则形状将是一个数字,在逗号后为空白。对于2+维,在所有逗号之后都会有一个数字。# 1 dimension with 2 elements, shape = (2,). # Note there's nothing after the comma.z=np.array([ # start dimension
10, # not a dimension
20 # not a dimension]) # end dimensionprint(z.shape)(2,)# 2 dimensions, each with 1 element, shape = (2,1)w=np.array([ # start outer dimension
[10], # element is in an inner dimension
[20] # element is in an inner dimension]) # end outer dimensionprint(w.shape)(2,1)