当前位置: 首页 > 知识库问答 >
问题:

为什么Numpy只有维度(n,)而不是维度(n,1)[重复]

谭嘉容
2023-03-14

我对此好奇已有一段时间了。我可以忍受,但如果没有足够的注意,它总是会咬我,所以我决定把它贴在这里。假设以下示例(Numpy版本=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和重塑的不同用法,但对我来说,这些函数更多的是混淆而不是帮助。如果像[1,2,3]这样的数组打印,那么直观地说维度应该是[1,3],而不是[3,],对吗?如果Numpy没有(n,),我只能看到清晰度的提高,而不是功能的损失。

因此,这背后一定有一些设计原因。我一直在不停地搜索,没有找到明确的答案或报告。有人能帮我澄清这一困惑或提供一些有用的参考资料吗?非常感谢你的帮助。

共有1个答案

古畅
2023-03-14

numpy的哲学不是说a[:,0]在一般情况下是“列向量”,而a[0,:]是“行向量”。更简单地说,它们都是向量,即只有一个维度的数组。这实际上是高度逻辑性和一致性的(但是,是的,对于我们这些习惯于Matlab的人来说可能会让人恼火)。

我之所以说“在一般情况下”,是因为numpy最通用的数据结构是数组,它适用于各种多维密集数据存储和操作应用程序,而不仅仅是矩阵数学。“行”和“列”是数组操作的高度专业化上下文,但是的,这是一个非常常见的上下文:这就是为什么numpy还提供matrix类的原因。将数组转换为numpy.matrix(或者首先使用matrix构造函数而不是array),您将看到更接近预期的行为。有关详细信息,请参见numpy数组和矩阵之间的区别?我应该用哪一个?

对于处理超过2个维度的情况,请查看numpy.expand_dims函数。尽管语法冗余得令人恼火,而且冗长得令人费解,但当我处理超过2维的数组时(所以不能使用矩阵),我永远不得不使用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的二维物体之间显然存在概念上的区别:后者可以在其第二维度上增长,而前者甚至不知道第二维度的含义以及为什么应该增长?因此,a.shape==(N,)a.shape==(N,1)作为单独的案例是完全合理的。你不妨问“为什么它不是(N,1,1)?”或者“为什么它不是(N,1,1,1,1,1)?”

 类似资料:
  • 我想知道为什么numpy中有一维的维度数组(length,1),也有一维的维数组(lendth,),没有第二个值。 我经常遇到这种情况,例如在使用< code>np.concatenate()时,这需要预先执行< code>reshape步骤(或者我可以直接使用< code > h stack /< code > v stack )。 我想不出这种行为可取的理由。有人能解释一下吗? 编辑:< br

  • 问题内容: 我刚刚开始学习数据结构,并且在进行数组插入时想知道为什么数组插入的时间复杂度为O(n)而不是O(n + 1)? 在最佳情况下,当插入在最后时,时间复杂度为O(1)。我想我们正在考虑1插入元素,因为这里没有元素被移动。在最坏的情况下,假设我们必须移动n个元素然后插入新元素,那么时间时间复杂度是否应该为O(n + 1)?n用于移动元素,1用于插入。 非常感谢您的帮助。 问题答案: O(n)

  • 我不确定numpy中(N,)和(N,1)之间的区别。假设两者都是一些特征,它们具有相同的N维,并且都有一个样本。有什么区别?

  • 问题内容: 在Java中,表达式为: 似乎等于: 尽管是有效的一元运算符,其优先级高于中的算术运算符。因此,编译器似乎假设该运算符不能为一元运算符,并解析该表达式。 但是,表达式: 即使存在以下唯一有效的解决方案,也不会编译: 和被指定为具有相同的优先级,那么为什么编译器为支持算术而解决看似模棱两可的问题,但为什么不这样做呢? 问题答案: 首先使用最大修改规则将文件标记化(转换为标记序列)-始终获

  • 问题内容: java.util.Random源代码的第294行说 为什么是这样? 问题答案: 该描述并不完全准确,因为0不是2的幂。更好的说法是 当n是2的幂或2的幂的负数或零时。 如果n是2的幂,则二进制中的n是单个1,后跟零。-n为2的补数是倒数+ 1,因此位排成一行 要了解其工作原理,请将二进制补码视为逆+ 1。 因为当您添加一个得到两个的补码时,您会一直进行到一个。 如果n不是2的幂,则结

  • 问题内容: 来自redis doc: ZPOPMIN键[count]自5.0.0起可用。 时间复杂度:O(log(N)* M),其中N为排序集中元素的数量,M为弹出元素的数量。 删除并返回存储在key排序集中的得分最低的成员。 因此,我的问题是,如果列表已排序,为什么要使用log n,为什么不使用O(1)? 问题答案: 如果 列表 已排序,为什么要使用log n,为什么不使用O(1)? 如果使用列