我正在使用numpy数组索引并发现这种奇怪的行为。当我使用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
list
也会发生某种奇怪的arr.flat
vs 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
和int a,b;
a = 0;
b = a + 2;
a = 3;
之间有什么区别?
Python 3.5.2
NumPy 1.11.1
答案 0 :(得分:2)
正在发生的事情称为花式索引,或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
但是,在索引表达式中使用 list (或数组)的行为会有所不同:
arr[[2,1]]
将索引到arr
,然后是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
得到的迭代器表现为1d数组。当你这样做
arr.flat[ [3, 4] ]
您使用花式索引访问该虚拟1d数组的两个元素;有用。但是当你想要做的时候
arr.flat[ (3,4) ]
您正在尝试访问1d(!)数组的(3,4)
元素,但这是错误的。这不会引发IndexError的原因可能只是因为arr.flat
本身处理了这个索引的情况。
答案 1 :(得分:1)
In [387]: arr=np.arange(10).reshape(5,2)
使用此列表,您将从arr
In [388]: arr[[1,1]]
Out[388]:
array([[2, 3],
[2, 3]])
与明确标记列切片(使用:或...)
相同In [389]: arr[[1,1],:]
Out[389]:
array([[2, 3],
[2, 3]])
使用数组而不是列表有效:arr[np.array([1,1]),:]
。 (这也消除了一些含糊之处。)
使用tuple
,结果与编写没有元组包装器的索引相同。因此它选择行索引为1,列索引为1的元素。
In [390]: arr[(1,1)]
Out[390]: 3
In [391]: arr[1,1]
Out[391]: 3
解释程序将arr[1,1]
翻译为arr.__getitem__((1,1))
。在Python中常见的1,1
是(1,1)
的缩写。
在arr.flat
个案例中,您将数组编入索引,就像它是1d一样。 np.arange(10)[[2,3]]
选择2项,而np.arange(10)[(2,3)]
是2d索引,因此错误。
最近的一些问题涉及一个更加混乱的角落案件。有时列表被视为元组。讨论可能具有启发性,但如果令人困惑,请不要去那里。