Kos*_*Kos 6 python indexing numpy
受到另一个问题的启发,我试图将我的思想包含在NumPy中的高级索引中,并建立更直观的理解它的工作原理.
我发现了一个有趣的案例.这是一个数组:
>>> y = np.arange(10)
>>> y
array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
Run Code Online (Sandbox Code Playgroud)
如果我将它标记为标量,我当然会得到一个标量:
>>> y[4]
4
Run Code Online (Sandbox Code Playgroud)
使用1D整数数组,我得到另一个1D数组:
>>> idx = [4, 3, 2, 1]
>>> y[idx]
array([4, 3, 2, 1])
Run Code Online (Sandbox Code Playgroud)
所以,如果我用2D整数数组对它进行索引,我得到......我得到了什么?
>>> idx = [[4, 3], [2, 1]]
>>> y[idx]
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
IndexError: too many indices for array
Run Code Online (Sandbox Code Playgroud)
不好了!对称性被打破了.我必须用3D数组索引才能获得2D数组!
>>> idx = [[[4, 3], [2, 1]]]
>>> y[idx]
array([[4, 3],
[2, 1]])
Run Code Online (Sandbox Code Playgroud)
是什么让numpy表现得这样?
为了使这更有趣,我注意到使用numpy数组(而不是列表)的索引表现我的直觉期望,2D给我2D:
>>> idx = np.array([[4, 3], [2, 1]])
>>> y[idx]
array([[4, 3],
[2, 1]])
Run Code Online (Sandbox Code Playgroud)
这与我所处的地方看起来不一致.这里的规则是什么?
原因是将列表解释为 numpy 数组的索引:列表被解释为元组,而元组索引被 NumPy 解释为多维索引。
\n就像返回与 和相同的arr[1, 2]元素一样,根据多维索引的规则返回元素和。arr[1][2]arr[[[4, 3], [2, 1]]]arr[[4, 3], [2, 1]]arr[4, 2]arr[3, 1]
通过添加另一个列表,您确实告诉 NumPy 您想要沿第一个维度进行切片,因为最外面的列表被有效地解释为好像您只传递了一个“第一个维度的索引列表”:arr[[[[4, 3], [2, 1]]]]。
从文档中:
\n\n\n例子
\n应从每一行中选择一个特定元素。行索引只是 [0, 1, 2],列索引指定为相应行选择的元素,此处为 [0, 1, 0]。将两者结合使用可以使用高级索引来解决任务:
\nRun Code Online (Sandbox Code Playgroud)\n>>> x = np.array([[1, 2], [3, 4], [5, 6]])\n>>> x[[0, 1, 2], [0, 1, 0]]\narray([1, 4, 5])\n
和:
\n\n\n警告
\n高级索引的定义意味着它
\nx[(1,2,3),]与x[(1,2,3)]. 后者相当于x[1,2,3]触发基本选择,而前者则触发高级索引。请务必了解为什么会发生这种情况。
在这种情况下,最好使用np.take:
>>> y.take([[4, 3], [2, 1]]) # 2D array\narray([[4, 3],\n [2, 1]])\nRun Code Online (Sandbox Code Playgroud)\n\n\n此函数 [
\nnp.take] 与 \xe2\x80\x9cfancy\xe2\x80\x9d 索引(使用数组索引数组)执行相同的操作;但是,如果您需要沿给定轴的元素,它会更容易使用。
或者将索引转换为数组。这样,NumPy 将其解释array为奇特索引(特殊情况!),而不是“多维索引”:
>>> y[np.asarray([[4, 3], [2, 1]])]\narray([[4, 3],\n [2, 1]])\nRun Code Online (Sandbox Code Playgroud)\n