使用列表和数组进行NumPy数组索引

7

我有:

>>> a
array([[1, 2],
       [3, 4]])

>>> type(l), l # list of scalers
(<type 'list'>, [0, 1])

>>> type(i), i # a numpy array
(<type 'numpy.ndarray'>, array([0, 1]))

>>> type(j), j # list of numpy arrays
(<type 'list'>, [array([0, 1]), array([0, 1])])

当我执行时
>>> a[l] # Case 1, l is a list of scalers

我明白了

array([[1, 2],
       [3, 4]])

这意味着索引仅在第 0 轴上发生。
但是,当我执行以下操作时:
>>> a[j] # Case 2, j is a list of numpy arrays

我理解了

array([1, 4])

这意味着索引沿轴0和轴1发生。
Q1:在用于索引时,为什么列表标量和numpy数组列表的处理有所不同?(情况1与情况2)。在情况2中,我希望只沿轴0进行索引,并得到
array( [[[1,2],
          [3,4]], 

        [[1,2],
         [3,4]]])

现在,当使用numpy数组的数组时:
>>> j1 = np.array(j) # numpy array of arrays

以下结果表明,索引仅沿轴0发生(如预期)。
>>> a[j1] Case 3, j1 is a numpy array of numpy arrays
array([[[1, 2],
        [3, 4]],

       [[1, 2],
        [3, 4]]])

问题2:当用于索引时,为什么对于numpy数组列表和numpy数组的numpy数组有所不同?(情况2与情况3)


对于Q1,非Numpy模拟使用k = [[0,1], [0,1]]; a[k]不是一样的吗?在这种情况下,您会看到列表和Numpy数组列表之间的相同行为。 - andrew_reece
另一种看待它的方式是,[a[jj] for jj in j] 给出了你在 Q1 中所期望的结果。输入一个列表的列表,无论是 Numpy 数组还是其他类型,基本上都是一次返回一组索引。 - andrew_reece
2个回答

2

情况1,a[l]实际上是a[(l,)],它展开为a[(l, slice(None))]。也就是说,使用列表l索引第一个维度,并自动添加一个结尾的:切片。索引作为元组传递给数组__getitem__,可以添加额外的()而不会混淆。

情况2,a[j]被视为a[array([0, 1]), array([0, 1]]a[(array(([0, 1]), array([0, 1])]。换句话说,作为每个维度的索引对象的元组。它最终返回a[0,0]a[1,1]

情况3,a[j1]a[(j1, slice(None))],只将j1索引应用于第一个维度。

情况2有点反常。你的直觉是正确的,但由于历史原因,这个数组列表(或列表列表)被解释为数组的元组。

这个问题在其他SO问题中讨论过,我认为它已经被记录下来了。但我无法手头找到那些参考资料。

因此,更安全的做法是使用索引对象的元组或数组。使用列表进行索引可能存在潜在的歧义。


numpy数组索引:列表索引和np.array索引会产生不同的结果

这个SO问题涉及到相同的问题,尽管最清晰的陈述实际上埋藏在评论者@user2357112的代码链接中。

另一种强制使用类似情况3的索引的方法是,显式地将第二个维度切片,a[j,:]

In [166]: a[j]
Out[166]: array([1, 4])
In [167]: a[j,:]
Out[167]: 
array([[[1, 2],
        [3, 4]],

       [[1, 2],
        [3, 4]]])

即使不需要,我经常在末尾包含:。这可以让我和读者清晰地知道我们正在处理多少个维度。


0

A1: l 的结构和 j 不一样。

l 只有一维,而 j则有两维。如果你改变其中一个:

# l = [0, 1]                                 # just one dimension!
l = [[0, 1], [0, 1]]                         # two dimensions
j = [np.array([0,1]), np.array([0, 1])]      # two dimensions

它们的行为相同。

A2:在第二种情况和第三种情况中,数组的结构不同。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接