【问题标题】:why there is a difference in the output of the same indexing selection inside a numpy array为什么numpy数组中相同索引选择的输出存在差异
【发布时间】:2020-10-04 15:59:22
【问题描述】:

假设我有一个看起来像这样的二维 NumPy 数组,我想提取左下角的正方形 (4x4):

arr_2d = [[ 5,10,15],
          [20,25,30],
          [35,40,45]]

为什么这种方式有区别:

arr_2d[row,col]

这样:

arr_2d[row][col]

我说这是有区别的,因为我在尝试这样做时得到了不同的输出:

arr_2d[1:3,1:3] #output was: [[25,30],
                              [40,45]]

arr_2d[1:3][1:3] #output was: [[35, 40, 45]]

如果我的问题错了,请告诉我为什么?

提前致谢!

【问题讨论】:

标签: python numpy numpy-slicing numpy-indexing


【解决方案1】:

假设 arr_2d 被声明为 numpy 数组:

import numpy as np
arr_2d = np.array([[5, 10, 15],
                   [20, 25, 30],
                   [35, 40, 45]])

然后,arr_2d[1:3, 1:3] 将从每个维度返回具有元素 1 和 2 的子矩阵(注意 Python 从 0 开始索引)。

arr_2d[1:3][1:3] 被解释为索引两次:

  • 第一个 arr_2d[1:3] 占用第 1 行和第 2 行:rows_1_2 = np.array([[20, 25, 30], [35, 40, 45]])

  • 然后,该结果再次使用[1:3] 进行索引,因此rows_1_2[1:3] 将给出rows_1_2 的第1 行和第2 行。由于该数组中不存在第 2 行,因此仅返回第 1 行,因此 [[35, 40, 45]]。请注意,这是一个 1x3 数组。

一般来说,强烈建议使用'slice indexing',因为索引 2 次对于大型数组来说可能会不必要地变慢。

请注意,对于标准 Python 列表,要获得类似的子矩阵,您需要将其编写为:

list_2d = ([[5, 10, 15],
            [20, 25, 30],
            [35, 40, 45]])
[row[1:3] for row in list_2d[1:3]] # result: [[25, 30], [40, 45]]

对于大型列表,这既难以阅读,又慢得多。但请注意,标准 Python 可以处理不同类型和长度的子列表,而 numpy 需要相同大小和类型的所有内容。

切片和broadcasting 使带有 numpy 的 Python 非常适合数字操作和计算。

【讨论】:

    【解决方案2】:

    切片有一个顺序:当我做时

    arr_2d[1:3]
    

    我得到 [[20 25 30],[35 40 45]]

    所以我第二次使用它

    arr_2d[1:3][1:3]
    

    我得到 [[35 40 45]]

    【讨论】:

      【解决方案3】:

      您必须了解,当使用[] 索引对象时,您调用的是在对象类中定义的__getitem__ 方法。现在 numpy 以两种方式定义索引。在您的第一种情况下,您使用与两个参数一起使用并且应该索引矩阵的那个,如

      arr_2d[0:2, 0:2]
      # returns [[5, 10], [20,25]]
      

      在第二种情况下,您使用与普通列表索引几乎相同的定义(接受一个参数的那个)。您正在对数组进行两次切片,如下所示

      a1 = arr_2d[1:3] # gets [[20,25,30], [35,40,45]]
      a1[1:3] # returns [[35,40,45]]
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-02-07
        • 1970-01-01
        • 2017-12-07
        • 2021-10-17
        • 2015-01-14
        相关资源
        最近更新 更多