给定的numpy代码发生了什么?我对最后一行print()语句感到困惑
print()语句会打印数组X的行吗?
import numpy as np
X = np.arange(12).reshape((3, 4))
row = np.array([0, 1, 2])
mask = np.array([1, 0, 1, 0], dtype=bool)
print(X[row[:, np.newaxis], mask])
X = [[0, 1, 2, 3],
[4, 5, 6, 7],
[8, 9, 10, 11]]
row = [0, 1, 2]
mask = [True, False, True, False]
在添加一个新轴后,数组的行变成了一个二维数组。这个行的形状是(3,1)
row = [[0],
[1],
[2]]
在print()之后,结果是什么样的?怎么回事?
[[0, 2],
[4, 6],
[8, 10]]
1 个回答
0
为了理解给出的Python代码及其生成的输出,我们一步一步来分析,重点关注几个关键部分:NumPy数组、索引和形状的操作,以便进行高级选择。
1. 创建NumPy数组
代码首先创建了一个名为X的二维NumPy数组:
X = np.arange(12).reshape((3, 4))
- np.arange(12)生成了一个包含从0到11的数字的一维数组。
- .reshape((3, 4))将这个数组重新调整为一个有3行4列的二维数组:
[[ 0, 1, 2, 3], [ 4, 5, 6, 7], [ 8, 9, 10, 11]]
2. 索引数组
接下来定义了两个额外的数组:
- row = np.array([0, 1, 2]) 指定了行的索引。
- mask = np.array([1, 0, 1, 0], dtype=bool) 是一个布尔掩码,用于选择列。
由于True对应1,False对应0,所以它实际上变成了[True, False, True, False],这意味着它会选择第一和第三列,而跳过第二和第四列。
3. 添加新轴
- row[:, np.newaxis] 将row从一维数组([0, 1, 2])转换为二维数组,方法是添加一个新轴:
[[0], [1], [2]]
这种形状的变化对下一步非常重要。
4. 高级索引
表达式X[row[:, np.newaxis], mask]对X进行高级索引:
- row[:, np.newaxis] 指示要选择哪些行,它的二维形状允许广播。
- mask根据布尔值选择列。
由于row已经被调整为二维数组,而mask是一个一维布尔数组,NumPy会对它们进行广播,以便逐元素选择。这意味着对于row中指定的每一行,它会选择mask为True的元素。
5. 结果解释
最终输出是:
[[ 0, 2], [ 4, 6], [ 8, 10]]
结果是这样得出的:
- 对于第一行[0, 1, 2, 3],应用掩码[True, False, True, False]得到[0, 2]。
- 对于第二行[4, 5, 6, 7],同样的掩码得到[4, 6]。
- 对于第三行[8, 9, 10, 11],掩码再次得到[8, 10]。
因此,这个操作从第一行选择了元素[0, 2],从第二行选择了[4, 6],从第三行选择了[8, 10],与指定的行索引和列掩码相符。这展示了NumPy高级索引功能的强大,能够通过广播和布尔掩码进行复杂的选择。