【问题标题】:numpy array indexing with lists and arraysnumpy 数组索引与列表和数组
【发布时间】:2018-05-29 08:11:05
【问题描述】:

我有:

>>> 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 发生并得到 ​​p>

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]]])

Q2:当用于索引时,为什么numpy数组的list和numpy数组的numpy数组有区别? (案例 2 与案例 3)

【问题讨论】:

  • 对于 Q1,非 Numpy 模拟不是要使用 k = [[0,1], [0,1]]; a[k] 吗?在这种情况下,您会在列表列表和 Numpy 数组列表之间看到相同的行为。
  • 另一种看待它的方式是[a[jj] for jj in j] 为您提供了您对第一季度的期望。输入列表列表,无论是否为 Numpy 数组,基本上都是一次返回一组索引。

标签: python arrays numpy


【解决方案1】:

Case1, 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 索引仅应用于第一个维度。

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

这已在其他 SO 问题中讨论过,我认为它已记录在案。但是我暂时找不到那些参考资料。

因此,使用索引对象的元组或数组更安全。使用列表进行索引可能会产生歧义。


numpy array indexing: list index and np.array index give different result

这个 SO question 涉及到同样的问题,尽管最清晰的关于正在发生的事情的陈述隐藏在 @user2357112 评论中的代码链接中。

另一种强制 Case3 类似索引的方式,使第 2 维切片显式,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]]])

(即使不需要,我也经常包含尾随 :。它让我和读者清楚地知道我们正在处理多少维度。)

【讨论】:

    【解决方案2】:

    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:同理,Case 2和Case 3的数组结构不一样。

    【讨论】:

      猜你喜欢
      • 2021-12-28
      • 2023-03-30
      • 2022-01-25
      • 2015-04-14
      • 2019-04-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多