(十)axis 指定被合并的轴
1. 从一列和一行分别手算
继续使用三天两时段的数据。统计每个时段的总量,需要固定时段,把三天合在一起:早上 10+30+50=90,晚上 20+40+60=120。被合并的是天,也就是 axis=0。
统计每天总量,则固定天,把早晚合在一起:[30,70,110]。被合并的是时段,axis=1。
# 项目文件:demos/reductions.py
# axis 指定被合并的轴;keepdims 用长度 1 保留轴位置,方便按原方向广播。
import numpy as np
a = np.array([[10, 20], [30, 40], [50, 60]])
print("全部", int(a.sum()))
print("沿天求和", a.sum(axis=0).tolist(), a.sum(axis=0).shape)
print("沿时段求和", a.sum(axis=1).tolist(), a.sum(axis=1).shape)
means = a.mean(axis=1, keepdims=True)
print("逐天均值", means.tolist(), means.shape)
print("逐天居中", (a - means).tolist())
square = a[:2]
print("形状碰巧能算但方向错", (square - square.mean(axis=1)).tolist())
cube = np.arange(12).reshape(2, 3, 2)
print("三维", cube.sum(axis=1).tolist(), cube.sum(axis=1).shape)
print("末轴", cube.sum(axis=-1).tolist())| 运算 | 被合并的轴 | 保留下来的信息 | shape |
|---|---|---|---|
a.sum() |
所有轴 | 总量 210 | 标量 |
a.sum(axis=0) |
天 | 早上 90、晚上 120 | (2,) |
a.sum(axis=1) |
时段 | 三天分别为 30、70、110 | (3,) |
axis 不是“按行还是按列”的口诀,而是指定哪一个轴参与合并。把轴的业务含义写清,扩展到三维时也可以沿用。
2. keepdims 让结果回到原来的对应位置
每天早晚的均值为 15、35、55。减去当天均值时,每天需要一份数值沿两列使用,因此均值保留为 (3,1);mean(axis=1,keepdims=True) 正好把被合并轴的长度变成 1。结果每行都是 [-5,5]。
只看“能运行”会漏掉方向错误。前两天组成 (2,2) 时,不保留轴的行均值为 (2,),相减也能广播,却变成每列分别减去 15、35,结果为 [[-5,-15],[15,5]],与每天居中不同。
3. 三维数组继续按轴含义归约
示例 cube 的 shape 为 (2,3,2),解释为两位读者、三天、早晚。sum(axis=1) 合并三天,留下每位读者的两个时段,shape 为 (2,2),结果 [[6,9],[24,27]]。
axis=−1 表示最后一轴,即早晚时段;合并后 shape 为 (2,3)。需要保留所有轴位置时继续设置 keepdims,结果在被合并的位置保留长度 1。