1.高维数组索引和切片
高维数组的计算,先从二维数组开始,在二维数组中,每个索引处的元素不再是标量,而是一维数组。
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[2] 打印输出[7 8 9]
arr2d[0][2] 打印输出3
二维数组上进行索引的说明见下图。我将轴 0 视为数组的 “行” ,将轴 1 视为 “列” 会很有帮助。
在多维数组中,如果你省略后面的索引,返回的对象将是一个低维 ndarray,由沿较高维度的所有数据组成。例如在下面的 2 × 2 × 3 三维数组 arr3d 中:
arr3d = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
arr3d 输出如下:
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
arr3d[0] 输出索引位置0的第一个二维数组:
[[1 2 3]
[4 5 6]]
高维数组的元素赋值。对于上面的2 × 2 × 3 三维数组 arr3d,我们先拷贝下arr3d[0]这个位置的数据,old_values = arr3d[0].copy() 然后再给arr3d[0] 重新赋值 :arr3d[0] = 66
输出整个arr3d如下:
[[[66 66 66]
[66 66 66]]
[[ 7 8 9]
[10 11 12]]] 从输出结果可以看到,arr3d数组索引位置为0的二维数组的每个元素都被重新赋值为66了。因为我们用old_values保存了arr3d[0]的副本,可以将其赋值还原回去,如下:
arr3d[0] = old_values 重新输出arr3d如下:
[[[ 1 2 3]
[ 4 5 6]]
[[ 7 8 9]
[10 11 12]]]
用多维索引,arr3d[1,0] 则输出 [7 8 9],或者 x = arr3d[1] 再通过x[0] 输出[7 8 9];arr3d[1,0,0]则输出7。
像一维数组类似,也可以对高维数组进行切片索引。
一维数组
arr=np.arange(10)
arr[1:6] 输出[1 2 3 4 5]
二维数组
arr2d = np.array([[1, 2, 3], [4, 5, 6], [7, 8, 9]])
arr2d[:2] 输出第0行和第1行,不包括2,如下
[[1 2 3]
[4 5 6]]
[:2]未指定开始索引,默认从0开始。
arr2d[:2, 1:] 用二维索引 :2表示输出0到1行,1: 表示输出第一列开始的所有列,输出结果如下:
[[2 3]
[5 6]]
还可以如下使用索引切片来降维:
lower_dim_slice = arr2d[1, :2] 中括号中的1表示只取第一行,:2 表示取第0列开始到第二列,这样就获得了一个一维数组[4 5], 用ndim属性检测 lower_dim_slice.ndim输出1。类似的我可以选择第三列(如果以索引第0列开始,则是第2列),但只能选择前两行形成一个一维数组:arr2d[:2, 2] 输出[3 6]。
arr2d[:, :1] ":"冒号前后不带数字,这里表示取所有行,索引第0列,输出结果如下:
[[1]
[4]
[7]]
所以,我们也可以通过这种方式给数组元素进行重新赋值,如下示例:
arr2d[:2, 1:] = 0 将相应位置的元素赋值为0,arr2d数组输出如下:
[[1 0 0]
[4 0 0]
[7 8 9]]
下面用图形来表示切片所取得子集以及子集得形状。
布尔索引
我们先定义一个元素值为字符串的一维数组names,再定义一个二维数组data,names数组中的每个元素对应data数组的一行。如下:
names = np.array(["Bob", "Joe", "Will", "Bob", "Will", "Joe", "Joe"])
data = np.array([[4, 7], [0, 2], [-5, 6], [0, 0], [1, 2], [-12, -4], [3, 4]])
如果我们要选择"Bob"值对应的data数组的行,可以如下操作:
names=="Bob" 输出[ True False False True False False False]
data[names=='Bob'] 这样的索引会输出上面True对应的data所在的行。结果如下:
[[4 7]
[0 0]] 这就是布尔索引的基本用法。还有很多扩展的布尔索引用法,如下:
data[names == "Bob", 1:] 输出:
[[7]
[0]] 后面的"1:" 对布尔索引后的子集再进行切片,输出所有行的第1列,结果是二维数组。
data[names == "Bob", 1] 输出 [7 0] ,这里注意1后面不带冒号,选择布尔索引后的子集的每行的第1列的元素组成一维数组。
总之,用布尔索引相应位置为True的元素才会选中。
休息下,下回接着学Python numpy高维数组的索引和计算。