猿问

numpy.Array形状(R,1)和(R,)之间的差异

numpy.Array形状(R,1)和(R,)之间的差异

在……里面numpy,一些操作将恢复形状。(R, 1)但有些人回来了(R,)..这将使矩阵乘法由于显式而变得更加繁琐。reshape是必需的。例如,给定一个矩阵M,如果我们想numpy.dot(M[:,0], numpy.ones((1, R)))哪里R行数(当然,同样的问题也发生在列上)。我们会得到matrices are not aligned错误自M[:,0]形似(R,)numpy.ones((1, R))形似(1, R).

所以我的问题是:

  1. 形状之间有什么区别(R, 1)(R,)..我知道字面上是数字列表和列表,其中所有列表都只包含一个数字。只是想知道为什么不设计numpy所以它更喜欢形状(R, 1)而不是(R,)为了更容易的矩阵乘法。

  2. 是否有更好的方法来做上面的例子?而不像这样显式地重塑:numpy.dot(M[:,0].reshape(R, 1), numpy.ones((1, R)))


慕田峪7331174
浏览 1435回答 3
3回答

蓝山帝景

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)

喵喔喔

.之间的区别(R,)和(1,R)字面上是你需要使用的索引的数量。ones((1,R))是碰巧只有一行的二维数组。ones(R)是一个向量。通常,如果变量有多个行/列没有意义,则应该使用向量,而不是单例维度的矩阵。对于您的具体情况,有几个选项:1)只需将第二个参数设为向量即可。下列各项运作良好:    np.dot(M[:,0], np.ones(R))2)如果您想要类似于matlab的矩阵运算,请使用以下类matrix而不是ndarray..所有的矩阵都被迫形成二维数组和运算符。*做矩阵乘法而不是按元素计算(所以你不需要点)。在我的经验,这是更多的麻烦,这是值得的,但它可能是不错的,如果你习惯了MATLAB。

富国沪深

这个形状是一个元组。如果只有一维,则形状将是一个数字,在逗号后为空白。对于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)
随时随地看视频慕课网APP

相关分类

Python
我要回答