我一直对此感到好奇。我可以忍受这种情况,但是如果不采取足够的照顾,它总会咬我,所以我决定将它发布在这里。假设以下示例(Numpy version = 1.8.2):
a = array([[0, 1], [2, 3]])
print shape(a[0:0, :]) # (0, 2)
print shape(a[0:1, :]) # (1, 2)
print shape(a[0:2, :]) # (2, 2)
print shape(a[0:100, :]) # (2, 2)
print shape(a[0]) # (2, )
print shape(a[0, :]) # (2, )
print shape(a[:, 0]) # (2, )
我不知道其他人的感受,但结果让我觉得不一致。最后一行是列向量,而倒数第二行是行向量,它们应该有不同的维度 - 在线性代数中它们可以做到! (第5行是另一个惊喜,但我暂时忽略它)。考虑第二个例子:
solution = scipy.sparse.linalg.dsolve.linsolve.spsolve(A, b) # solution of dimension (n, )
analytic = reshape(f(x, y), (n, 1)) # analytic of dimension (n, 1)
error = solution - analytic
现在错误是维度(n,n)。是的,在第二行我应该使用(n,)而不是(n,1),但为什么呢?我以前经常使用MATLAB,其中一维向量具有维度(n,1),linspace / arange返回维度(n,1)的数组,并且从不存在(n,)。但是在Numpy(n,1)和(n,)共存时,维度处理有很多功能:至少,newaxis和reshape的不同用途,但对我来说,这些功能更多的是混乱而不是帮助。如果数组打印如[1,2,3],那么直观地说维度应该是[1,3]而不是[3,],对吗?如果Numpy没有(n,),我只能看到清晰度的增益,而不是功能上的损失。
因此必须有一些设计理由。我一直在搜索,没有找到明确的答案或报告。有人可以帮助澄清这种混乱或为我提供一些有用的参考吗?非常感谢您的帮助。
答案 0 :(得分:6)
numpy
philosphy不是a[:, 0]
是"列向量"和a[0, :]
a"行向量"在一般情况下。相反,它们非常简单地是矢量 - 即。只有一个维度的数组。这实际上是高度逻辑和一致的(但是,对于习惯于Matlab的人来说,这会让人讨厌)。
我说"在一般情况下"因为numpy最常用的数据结构array
适用于所有类型的多维密集数据存储和操作应用程序,而不仅仅是矩阵数学。有"行"和"列"是一个高度专业化的数组操作上下文 - 但是,是一个非常常见的上下文:这就是为什么numpy
也提供matrix
类的原因。将您的数组转换为numpy.matrix
(或使用matrix
构造函数而不是array
开头),您将看到更接近您期望的行为。有关详细信息,请参阅What are the differences between numpy arrays and matrices? Which one should I use?
如果您处理的维度超过2个,请查看numpy.expand_dims
功能。虽然语法冗长而且非常冗长,但是当我处理具有2个以上维度的数组时(因此无法使用matrix
),我永远不得不使用expand_dims
来做这种事:
A -= numpy.expand_dims( A.mean( axis=2 ), 2 ) # subtract mean-across-layers from A
而不是
A -= A.mean( axis=2 ) # throw an exception while naively attempting to subtract mean-across-layers from A
但相比之下,请考虑Matlab。 Matlab隐含地声称没有一维对象这样的东西,并且事物所能拥有的最小维数是2.当然,你和我都非常习惯于此,但是花点时间才意识到它是多么随意它是。在一个基本上是一维的对象和一个二维对象之间存在明显的概念差异,这个对象恰好在其一个维度中具有范围1:后者被允许在其第二维度上增长,而前者没有&#39甚至不知道第二个维度意味着什么 - 为什么要这样?因此,a.shape==(N,)
和a.shape==(N,1)
作为单独的案例具有完美的意义。你也可以问"为什么不是(N, 1, 1)
?"或者"为什么不是(N, 1, 1, 1, 1, 1, 1)
?"