为什么 numpy 数组中相同索引选择的输出存在差异
why there is a difference in the output of the same indexing selection inside a numpy array
假设我有一个看起来像这样的二维 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]]
如果我的问题有误,你能告诉我为什么吗?
提前致谢!
切片有顺序:当我做的时候
arr_2d[1:3]
我得到 [[20 25 30],[35 40 45]]
所以我第二次使用它
arr_2d[1:3][1:3]
我得到 [[35 40 45]]
假设 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]
将从每个维度return具有元素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 行 returned,因此 [[35, 40, 45]]
。请注意,这是一个 1x3 数组。
一般来说,强烈建议使用'slice indexing',因为对于大型数组,索引 2 次可能会不必要地慢。
请注意,对于标准 Python 列表,要获得类似的 sub-matrix,您需要将其写为:
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 使 Python with numpy 非常适合数字操作和计算。
您必须了解,当使用 []
索引对象时,您正在调用对象 class 中定义的 __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]]
假设我有一个看起来像这样的二维 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]]
如果我的问题有误,你能告诉我为什么吗?
提前致谢!
切片有顺序:当我做的时候
arr_2d[1:3]
我得到 [[20 25 30],[35 40 45]]
所以我第二次使用它
arr_2d[1:3][1:3]
我得到 [[35 40 45]]
假设 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]
将从每个维度return具有元素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 行 returned,因此[[35, 40, 45]]
。请注意,这是一个 1x3 数组。
一般来说,强烈建议使用'slice indexing',因为对于大型数组,索引 2 次可能会不必要地慢。
请注意,对于标准 Python 列表,要获得类似的 sub-matrix,您需要将其写为:
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 使 Python with numpy 非常适合数字操作和计算。
您必须了解,当使用 []
索引对象时,您正在调用对象 class 中定义的 __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]]