如何在numpy中保持向量的行/列方向?
我之前使用过Matlab/Octave,现在在学习numpy。有一件事让我一直困惑,就是向量和多维数组之间的区别。为了更好地说明我的问题,我会给出一个具体的例子,但如果有人能帮我解释一下numpy中一维数组的整体概念、为什么我们需要它们、以及在混合一维和多维数组时如何避免麻烦,那就太好了。总之,我的问题是:
我有一个叫做X的二维数组:
X = numpy.arange(10).reshape(2,5)
我想把X的最后一列提取出来,存储为另一个二维数组(也就是一个列向量),叫做Y。我目前想到的唯一方法是:
Y = numpy.atleast_2d(X[:,4]).T
但我对这个方法有几个不太满意的地方:
我觉得在X[:,4]中,列的方向应该是显而易见的,我不应该还要告诉它要转置这个向量。
在代码中反复使用至少二维(atleast_2D)这个方法感觉很麻烦,这种情况会经常出现。我觉得我是不是做错了什么。
所以,简而言之,有没有更好的方法呢?
谢谢。
2 个回答
子集选择
更简单的方法是对矩阵进行子集选择。
>>> X
[[0 1 2 3 4]
[5 6 7 8 9]]
>>> X[:, [4]]
[[4]
[9]]
>>> X[:, 4]
[4 9]
这和Pandas的数据框有点像。如果你对数据框进行索引,它会给你一个序列。如果你对数据框进行子集选择或切片,它会给你一个数据框。
另见
首先,做你想要的事情有个简单的方法:
Y = X[:,4:]
现在,之前你尝试的时候,numpy没有这样做的原因和Python中数组的工作方式有关,这其实在大多数编程语言中都是一样的。当你写类似 a[4]
的东西时,这实际上是在访问数组的第五个元素,而不是给你原数组某个部分的视图。举个例子,如果 a
是一个数字数组,那么 a[4]
就只是一个数字。如果 a
是一个二维数组,也就是一个数组的数组,那么 a[4]
就会是一个一维数组。简单来说,访问数组元素的操作返回的东西维度会比原数组少一维。
现在,Python有一个叫“切片表示法”的东西,用冒号表示,这是访问数组元素的另一种方式。它不是返回一个元素(也就是比原数组少一维的东西),而是返回原数组某个部分的副本。基本上,a:b
表示从索引 a
(包含)到 b
(不包含)之间的所有元素。a
或 b
其中一个或两个都可以省略,这样切片就会一直到数组的相应末尾。
这对你的情况意味着,当你写 X[:,4]
时,你使用了一种切片表示法和一种常规索引表示法。切片表示法表示第一维的所有索引(因为数组有两行,所以就是0和1),而4表示第二维的第五个元素。每次使用常规索引基本上会让返回的对象的维度减少一维,所以因为 X
是一个二维数组,而你有一个常规索引,所以你得到的是一维的结果。Numpy只是把一维数组显示为行向量。如果你想得到和开始时一样维度的东西,那么就要使用全部的切片索引,就像我在这篇文章开头的例子中那样。
如果你想提取一个有超过5列的数组的第五列,你可以用 X[:,4:5]
。如果你想查看第3到第4行和第5到第7列,你可以用 X[3:5,5:8]
。希望你能明白这个意思。