我在玩 numpy 数组索引时发现了这种奇怪的行为。当我使用 np.array
或 list
进行索引时,它按预期工作:
In[1]: arr = np.arange(10).reshape(5,2)
arr[ [1, 1] ]
Out[1]: array([[2, 3],
[2, 3]])
但是当我放入 tuple
时,它给了我一个元素:
In[1]: arr = np.arange(10).reshape(5,2)
arr[ (1, 1) ]
Out[1]: 3
还有一些这种奇怪的 tuple
vs list
行为发生在 arr.flat
中:
In[1]: arr = np.arange(10).reshape(5,2)
In[2]: arr.flat[ [3, 4] ]
Out[2]: array([3, 4])
In[3]: arr.flat[ (3, 4) ]
Out[3]: IndexError: unsupported iterator index
我不明白引擎盖下发生了什么?在这种情况下,tuple
和 list
有什么区别?
python 3.5.2
NumPy 1.11.1
最佳答案
发生的事情称为花式索引,或 advanced indexing .使用切片索引或使用列表/数组进行索引之间存在差异。诀窍是由于隐式元组语法,多维索引实际上适用于元组:
import numpy as np
arr = np.arange(10).reshape(5,2)
arr[2,1] == arr[(2,1)] # exact same thing: 2,1 matrix element
但是,在索引表达式中使用列表(或数组)会有不同的表现:
arr[[2,1]]
将索引到 arr
1,然后是 2,所以首先它获取 arr[2]==arr[2,:]
,然后是 arr [1]==arr[1,:]
,返回这两行(第2行和第1行)作为结果。
它变得更有趣:
print(arr[1:3,0:2])
print(arr[[1,2],[0,1]])
第一个是常规索引,它对行 1 到 2 和列 0 到 1 进行切片;给你一个 2x2 子数组。第二个是奇特的索引,它为您提供数组中的 arr[1,0],arr[2,1]
,即它使用 zip 有选择地索引到您的数组中()
的索引列表。
现在这就是为什么 flat
如此工作的原因:它返回数组的 flatiter
。来自 help(arr.flat)
:
class flatiter(builtins.object)
| Flat iterator object to iterate over arrays.
|
| A `flatiter` iterator is returned by ``x.flat`` for any array `x`.
| It allows iterating over the array as if it were a 1-D array,
| either in a for-loop or by calling its `next` method.
因此 arr.flat
的结果迭代器表现为一维数组。当你做的时候
arr.flat[ [3, 4] ]
您正在使用花式索引访问该虚拟一维数组的两个元素;有用。但是当你想做的时候
arr.flat[ (3,4) ]
您正在尝试访问一维 (!) 数组的 (3,4)
元素,但这是错误的。这不会引发 IndexError 的原因可能只是因为 arr.flat
本身会处理这种索引情况。
关于python - Numpy 数组索引行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41245349/