繁体   English   中英

Numpy数组索引行为

[英]Numpy array indexing behavior

我正在玩numpy数组索引并发现这种奇怪的行为。 当我使用np.arraylist索引时,它按预期工作:

 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一起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

我无法理解引擎盖下发生了什么? 在这种情况下, tuplelist什么区别?

Python 3.5.2
NumPy 1.11.1

发生的事情被称为花式索引或高级索引 使用切片或列表/数组进行索引之间存在差异。 诀窍在于,由于隐式元组语法,多维索引实际上与元组一起使用:

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的结果迭代器表现为1d数组。 当你这样做

arr.flat[ [3, 4] ]

你正在使用花式索引访问该虚拟1d数组的两个元素; 有用。 但是当你想要做的时候

arr.flat[ (3,4) ]

你试图访问1d(!)数组的(3,4)元素,但这是错误的。 这不会抛出IndexError的原因可能只是因为arr.flat本身处理这个索引的情况。

In [387]: arr=np.arange(10).reshape(5,2)

使用此列表,您将从arr中选择2行

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索引,因此是错误。

最近几个问题涉及一个更加混乱的角落案件。 有时列表被视为元组。 讨论可能具有启发性,但如果令人困惑,就不要去那里。

传递列表时的高级切片而不是numpy中的元组

numpy索引:不应该落后省略号是多余的?

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM