考虑到:
test = numpy.array([[1, 2], [3, 4], [5, 6]])
Test [i]给出第i行(例如[1,2])。如何访问第I列?(例如[1,3,5])。还有,这手术会很贵吗?
考虑到:
test = numpy.array([[1, 2], [3, 4], [5, 6]])
Test [i]给出第i行(例如[1,2])。如何访问第I列?(例如[1,3,5])。还有,这手术会很贵吗?
当前回答
如果你想一次访问多个列,你可以这样做:
>>> 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]])
其他回答
访问列0:
>>> test[:, 0]
array([1, 3, 5])
访问第0行:
>>> test[0, :]
array([1, 2])
这在NumPy引用的第1.4节(索引)中介绍。这很快,至少以我的经验来看。这当然比在循环中访问每个元素要快得多。
虽然这个问题已经得到了回答,但让我提一下一些细微差别。
假设你对数组的第一列感兴趣
arr = numpy.array([[1, 2],
[3, 4],
[5, 6]])
正如你已经从其他答案中知道的那样,要以“行向量”(shape(3,)数组)的形式得到它,你使用切片:
arr_col1_view = arr[:, 1] # creates a view of the 1st column of the arr
arr_col1_copy = arr[:, 1].copy() # creates a copy of the 1st column of the arr
要检查一个数组是否是另一个数组的视图或副本,您可以执行以下操作:
arr_col1_view.base is arr # True
arr_col1_copy.base is arr # False
看到ndarray.base。
除了两者之间的明显差异(修改arr_col1_view将影响arr)之外,遍历它们的字节步数也是不同的:
arr_col1_view.strides[0] # 8 bytes
arr_col1_copy.strides[0] # 4 bytes
看大步和这个答案。
为什么这很重要?假设你有一个非常大的数组a而不是arr:
A = np.random.randint(2, size=(10000, 10000), dtype='int32')
A_col1_view = A[:, 1]
A_col1_copy = A[:, 1].copy()
并且您希望计算第一列所有元素的和,即A_col1_view.sum()或A_col1_copy.sum()。使用复制的版本要快得多:
%timeit A_col1_view.sum() # ~248 µs
%timeit A_col1_copy.sum() # ~12.8 µs
这是由于前面提到的不同的步幅:
A_col1_view.strides[0] # 40000 bytes
A_col1_copy.strides[0] # 4 bytes
虽然使用列复制似乎更好,但这并不总是正确的,因为复制也需要时间并使用更多内存(在这种情况下,它花费了我大约。200µs来创建A_col1_copy)。然而,如果我们首先需要副本,或者我们需要对数组的特定列做许多不同的操作,并且我们可以牺牲内存来换取速度,那么创建副本是可行的方法。
在我们主要对列感兴趣的情况下,以列为主('F')的顺序而不是行为主('C')的顺序(这是默认的)创建数组可能是一个好主意,然后像以前一样进行切片以获得一个列而不复制它:
A = np.asfortranarray(A) # or np.array(A, order='F')
A_col1_view = A[:, 1]
A_col1_view.strides[0] # 4 bytes
%timeit A_col1_view.sum() # ~12.6 µs vs ~248 µs
现在,在列视图上执行求和操作(或任何其他操作)与在列复制上执行求和操作一样快。
最后,让我注意一下,转置一个数组并使用行切片与在原始数组上使用列切片是一样的,因为转置是通过交换原始数组的形状和步长来完成的。
A[:, 1].strides[0] # 40000 bytes
A.T[1, :].strides[0] # 40000 bytes
如果你想一次访问多个列,你可以这样做:
>>> 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]])
>>> test[:,0]
array([1, 3, 5])
这个命令给了你一个行向量,如果你只是想循环遍历它,这是可以的,但如果你想hstack其他一些维度为3xN的数组,你会有
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]])
>>> 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]])