如何访问NumPy多维数组的第i列?

时间:2010-12-15 21:27:42

标签: python arrays numpy

假设我有:

test = numpy.array([[1, 2], [3, 4], [5, 6]])

test[i]获取数组的 ith 行(例如[1, 2])。如何访问 ith 列? (例如[1, 3, 5])。另外,这会是一项昂贵的操作吗?

8 个答案:

答案 0 :(得分:556)

>>> test[:,0]
array([1, 3, 5])

同样,

>>> test[1,:]
array([3, 4])

允许您访问行。这将在NumPy reference的第1.4节(索引)中介绍。这很快,至少在我的经验中。它肯定比访问循环中的每个元素快得多。

答案 1 :(得分:58)

如果您想要一次访问多个列:

>>> test = np.arange(9).reshape((3,3))
>>> test
array([[0, 1, 2],
       [3, 4, 5],
       [6, 7, 8]])
>>> test[:,[0,2]]
array([[0, 2],
       [3, 5],
       [6, 8]])

答案 2 :(得分:46)

>>> test[:,0]
array([1, 3, 5])

这个命令给你一个行向量,如果你只想循环它,它很好,但是如果你想要使用尺寸为3xN的其他数组进行hstack,你将会有

ValueError:所有输入数组必须具有相同的维数

,而

>>> test[:,[0]]
array([[1],
       [3],
       [5]])

为您提供列向量,以便您可以进行连接或hstack操作。

e.g。

>>> np.hstack((test, test[:,[0]]))
array([[1, 2, 1],
       [3, 4, 3],
       [5, 6, 5]])

答案 3 :(得分:19)

你也可以转置并返回一行:

In [4]: test.T[0]
Out[4]: array([1, 3, 5])

答案 4 :(得分:3)

要获得多个和独立的列,只需:

> test[:,[0,2]]

你会得到colums 0和2

答案 5 :(得分:3)

尽管问题已经回答,但我还是要提一些细微差别。

假设您对数组的第一列感兴趣

arr = numpy.array([[1, 2],
                   [3, 4],
                   [5, 6]])

从其他答案中已经知道,要以“行向量”(形状为(3,)的数组)的形式获取,请使用切片:

arr_c1_ref = arr[:, 1]  # creates a reference to the 1st column of the arr
arr_c1_copy = arr[:, 1].copy()  # creates a copy of the 1st column of the arr

要检查一个数组是视图还是另一个数组的副本,可以执行以下操作:

arr_c1_ref.base is arr  # True
arr_c1_copy.base is arr  # False

请参见ndarray.base

除了两者之间的明显区别(修改arr_c1_ref将影响arr)之外,遍历它们每个字节步长的数量也不同:

arr_c1_ref.strides[0]  # 8 bytes
arr_c1_copy.strides[0]  # 4 bytes

请参见strides。 为什么这很重要?假设您有一个很大的数组A而不是arr

A = np.random.randint(2, size=(10000,10000), dtype='int32')
A_c1_ref = A[:, 1] 
A_c1_copy = A[:, 1].copy()

,并且您要计算第一列的所有元素的总和,即A_c1_ref.sum()A_c1_copy.sum()。使用复制的版本要快得多:

%timeit A_c1_ref.sum()  # ~248 µs
%timeit A_c1_copy.sum()  # ~12.8 µs

这是由于前面提到的步幅不同:

A_c1_ref.strides[0]  # 40000 bytes
A_c1_copy.strides[0]  # 4 bytes

尽管使用列副本似乎更好,但由于创建副本需要花费时间并使用更多的内存(在这种情况下,我花了大约200 µs的时间来创建{{1} }。但是,如果首先需要复制,或者需要在数组的特定列上执行许多不同的操作,并且可以牺牲内存以提高速度,那么复制是可行的方法。

如果我们感兴趣的是主要使用列,那么最好以列大('F')顺序而不是行大('C')顺序(即是默认设置),然后像以前一样进行切片以获取一列而不复制它:

A_c1_copy

现在,在列视图上执行求和运算(或其他任何运算)要快得多。

最后让我注意到,转置数组并使用行切片与在原始数组上使用列切片相同,因为转置是通过交换原始数组的形状和步幅来完成的。

A = np.asfortranarray(A)  # or np.array(A, order='F')
A_c1_ref = A[:, 1]
A_c1_ref.strides[0]  # 4 bytes
%timeit A_c1_ref.sum()  # ~12.6 µs vs ~248 µs

答案 6 :(得分:2)

>>> test
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])

>>> ncol = test.shape[1]
>>> ncol
5L

然后你可以这样选择第2到第4列:

>>> test[0:, 1:(ncol - 1)]
array([[1, 2, 3],
       [6, 7, 8]])

答案 7 :(得分:0)

这不是多维的。它是二维数组。您想要访问的列的位置。

test = numpy.array([[1, 2], [3, 4], [5, 6]])
test[:, a:b]  # you can provide index in place of a and b