Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/arrays/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 如何访问NumPy多维数组的第i列?_Python_Arrays_Numpy - Fatal编程技术网

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

Python 如何访问NumPy多维数组的第i列?,python,arrays,numpy,Python,Arrays,Numpy,假设我有: test = numpy.array([[1, 2], [3, 4], [5, 6]]) test[i]获取数组的第i行(例如[1,2])。如何访问第I列?(例如[1,3,5])。还有,这会是一个昂贵的手术吗 >>> test[:,0] array([1, 3, 5]) 同样地 >>> test[1,:] array([3, 4]) 允许您访问行。本手册第1.4节(索引)对此进行了介绍。这很快,至少在我的经验中是这样。它肯定比访问循环中的每个

假设我有:

test = numpy.array([[1, 2], [3, 4], [5, 6]])
test[i]
获取数组的第i行(例如
[1,2]
)。如何访问第I列?(例如
[1,3,5]
)。还有,这会是一个昂贵的手术吗

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

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

允许您访问行。本手册第1.4节(索引)对此进行了介绍。这很快,至少在我的经验中是这样。它肯定比访问循环中的每个元素快得多。

如果您想一次访问多个列,可以执行以下操作:

>>> 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]])
这个命令会给你一个行向量,如果你只想在它上面循环,这很好,但是如果你想用其他的3xN维数组进行hstack,你就需要

为您提供列向量,以便您可以执行串联或hstack操作

e、 g

然后,您可以通过以下方式选择第2列至第4列:

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

您还可以转置并返回一行:

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

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

> test[:,[0,2]]

您将得到第0列和第2列

尽管问题已经得到了回答,但让我提一下一些细微差别

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

arr = numpy.array([[1, 2],
                   [3, 4],
                   [5, 6]])
正如您已经从其他答案中了解到的,要以“行向量”(形状数组
(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

除了两者之间的明显差异(修改
arr\u col1\u视图
将影响
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\u col1\u view.sum()
A\u col1\u 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_拷贝
)。但是,如果我们首先需要拷贝,或者我们需要对阵列的特定列执行许多不同的操作,并且我们可以牺牲内存来提高速度,那么制作拷贝就是一种方法

如果我们主要对列感兴趣,那么最好以列主('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[:,[0,2]]
只访问数据,例如,
test[:,[0,2]=某些东西将修改测试,而不会创建另一个数组。但是
copy\u test=test[:,[0,2]]
确实像你说的那样创建了一个副本。这样创建了一个副本,是否可以获得引用,就像我获得了对某些列的引用一样,引用中的任何更改都会反映在原始数组中?@harman786你可以将修改后的数组重新分配给旧数组。为什么
test[:,[0,2]]
只访问数据,而
测试[:,[0,2][:,[0,1]]]
不访问数据?再次做同样的事情会产生不同的结果,这似乎很不直观。索引一次也可以处理多个列,因此最后一个示例可以是test[:,[0,1,0]]或test[:,[range(test.shape[1])+[0]]]]+1,用于指定[:,[0]]vs[:,0]来获取列向量而不是行向量。这正是我想要的行为。另外,对于附加索引注释,将+1添加到lib。此答案应该与最上面的答案在一起。必须选择此答案感谢[:,[0]]。根据上面的答案,我尝试做一些类似于
test[:,0]的事情。至少可以说,重塑(test.shape[0],-1)
这是不好的。这样创建一个副本,是否可以获得引用,就像我获得一个列的引用一样,该引用中的任何更改都会反映在原始数组中。只是为了确保,考虑到test.shape=(2,x,y)。测试[:,0:,:,]是访问第一个“列”(坐标)的方法,对吗?如何选择多个列和多个行?@AAAlex123-参见Akavall的答案[@mtrw更准确地说,我指的是选择一系列列,而不是特定的列,例如列1-5。阅读文档时,我发现这种语法
a[a:b,c:d]
选择a到b行和c到d列。这与Akavall的有什么不同?在寻找访问列的最快方法之前,我已经做了一段时间了,我想知道这是更快、更慢,还是与test[:,[0]]相同
A = np.random.randint(2, size=(10000, 10000), dtype='int32')
A_col1_view = A[:, 1] 
A_col1_copy = A[:, 1].copy()
%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
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