【问题标题】:Indexing numpy multidimensional arrays depends on a slicing method索引 numpy 多维数组取决于切片方法
【发布时间】:2017-09-20 22:35:54
【问题描述】:

我有一个 3-D 数组。当我对其进行二维切片时,结果取决于它是使用列表还是切片进行索引。在第一种情况下,结果被转置。在manual 中没有发现这种行为。

>>> import numpy as np
>>> x = np.array([[[1,1,1],[2,2,2]], [[3,3,3],[4,4,4]]])
>>> x
array([[[1, 1, 1],
        [2, 2, 2]],
       [[3, 3, 3],
        [4, 4, 4]]])
>>> x[0,:,[0,1]]
array([[1, 2],
       [1, 2]])
>>> x[0,:,slice(2)]
array([[1, 1],
       [2, 2]])
>>> 

有人能指出原因吗?

【问题讨论】:

  • 奇怪的是a[0][:, [0, 1]] 给出了与使用 slice() 相同的结果。
  • 谢谢你,P. Camilleri。二维阵列的行为完全可以预测。问题在于三个维度,甚至更多维度。
  • stackoverflow.com/questions/27297445/… - 早期尝试解释混合索引。该主题之前出现过,但诀窍是找到一个好的搜索词。

标签: python numpy multidimensional-array slice


【解决方案1】:

据我了解,NumPy 在给出类似list/tuple 的索引时吐出结果时遵循轴编号理念。

array([[[1, 1, 1],
        [2, 2, 2]],

       [[3, 3, 3],
        [4, 4, 4]]])

当您已经指定了前两个索引 (x[0, :, ]),现在下一个问题是如何提取第三个维度。现在,当您指定元组(0,1) 时,它首先提取0th 切片轴,因此它得到[1, 2],因为它位于0th 轴上,然后它同样提取1st 切片并堆叠在已经存在的行下方[1, 2]。

[[1, 1, 1],          array([[1, 2],
 [2, 2, 2]]  =====>         [1, 2]])

(将此堆叠可视化如下(不在顶部)由于轴 0 向下增长,因此已经存在的行)

或者,当为索引指定slice(n) 时,它遵循切片理念 (start:stop:step)。请注意,在您的示例中,使用 slice(2) 基本上等于 0:2。因此,它首先提取[1, 1],然后提取[2, 2]。请注意,这里是 [1, 1] 如何在 [2, 2] 之上出现的,这里再次遵循相同的轴理念,因为我们还没有离开第三维。这就是为什么这个结果是另一个结果的转置。

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

另外,请注意,从 3-D 数组开始,这种一致性得以保留。下面是来自4-D 数组和切片结果的示例。

In [327]: xa
Out[327]: 
array([[[[ 0,  1,  2],
         [ 3,  4,  5],
         [ 6,  7,  8]],

        [[ 9, 10, 11],
         [12, 13, 14],
         [15, 16, 17]]],


       [[[18, 19, 20],
         [21, 22, 23],
         [24, 25, 26]],

        [[27, 28, 29],
         [30, 31, 32],
         [33, 34, 35]]]])

In [328]: xa[0, 0, :, [0, 1]]
Out[328]: 
array([[0, 3, 6],
       [1, 4, 7]])

In [329]: xa[0, 0, :, 0:2]
Out[329]: 
array([[0, 1],
       [3, 4],
       [6, 7]])

【讨论】:

    【解决方案2】:

    因为当您使用[0,1] 时,您实际上是在使用advanced indexing。来自docs:

    结合高级和基本索引

    当至少有一个 索引中的切片(:)、省略号(...)或np.newaxis(或数组有 比高级索引更多的维度),然后是行为 可能更复杂。 这就像连接索引结果 对于每个高级索引元素

    在最简单的情况下,只有一个高级索引。 单曲 例如,高级索引可以替换切片和结果数组 将是相同的,但是,它是一个副本,可能有不同的 内存布局。如果可能,最好使用切片。

    注意我上面加粗的两个部分。

    特别是在这个结构中:

    >>> x[0,:,[0,1]]
    array([[1, 2],
           [1, 2]])
    

    是索引中至少有一次“slice、ellipsisi 或 np.newaxis”的情况,其行为类似于为每个高级索引元素连接索引结果。所以:

    >>> x[0,:,[0]]
    array([[1, 2]])
    >>> x[0,:,[1]]
    array([[1, 2]])
    >>> np.concatenate((x[0,:,[0]], x[0,:,[1]]))
    array([[1, 2],
           [1, 2]])
    

    但是,这种构造就像简单的情况:只有一个高级索引,所以它就像一个切片:

    >>> x[0,:,slice(2)]
    array([[1, 1],
           [2, 2]])
    >>> x[slice(0,1),:,slice(2)]
    array([[[1, 1],
            [2, 2]]])
    

    虽然请注意,后者实际上是三维,因为索引的第一部分充当切片,它是 3 个切片,因此是三个维度。

    【讨论】:

    • 您的答案似乎缺少最后一部分,是否应该遵循“类似”?
    • 谢谢你,juanpa.arrivillaga。 Numpy 的样式应该更具功能性,即优化。
    • 在stackoverflow.com/questions/36207850/… 中,我找到了[scalar, slice, list] 索引情况下的错误/问题的链接。有关更多 SO 讨论,请搜索“[numpy] advanced-and-basic-indexing”。
    猜你喜欢
    • 2015-10-23
    • 2018-11-07
    • 1970-01-01
    • 2021-11-23
    • 2015-02-02
    • 1970-01-01
    • 2019-05-09
    • 2015-04-19
    相关资源
    最近更新 更多