本系列是《NumPy 速通》的配套章节。
对一整组数据算个总账——求和、均值、最大最小、方差等等。这些操作叫聚合(aggregation),因为它们把一堆数"聚合"成一个数。本章重点:axis 参数(90% 的坑都在这)和"忽略 NaN"的两个变体。
基本聚合函数
import numpy as np
arr = np.array([3, 1, 4, 1, 5, 9, 2, 6])
np.sum(arr) # 31 总和
np.mean(arr) # 3.875 平均
np.max(arr) # 9 最大
np.min(arr) # 1 最小
np.std(arr) # 标准差(sqrt(方差))
np.var(arr) # 方差
np.median(arr) # 3.5 中位数(不受极端值影响)
np.prod(arr) # 连乘
np.cumsum(arr) # [3 4 8 9 14 23 25 31] 累积和
💡 均值 vs 中位数:均值对极端值(outlier)敏感,中位数稳健。工资数据被几个富豪拉高时,用中位数更能反映"普通人"水平。np.cumsum(累积和)常用于画累积分布、算前缀和。
⚠️ 灵魂警告:NaN 会污染聚合结果
data = np.array([1.0, 2.0, np.nan, 4.0])
np.mean(data) # nan ⚠️ 一个 nan 就毁掉整个均值!
解决方案——忽略 NaN 的版本(每个聚合函数都有):
np.nanmean(data) # 2.333 忽略 nan 再平均
np.nansum(data) # 7.0
np.nanmax(data) # 4.0
np.nanstd(data) # 忽略 nan 的标准差
真实数据(传感器、爬虫、问卷)几乎必然有缺失值。先
np.isnan(data).any()检查,再用 nan 系列函数,是数据清洗的基本功。
⭐ axis 参数 —— 最关键的技能
二维数组聚合时,axis 决定"沿着哪个方向算":
arr = np.array([[1, 2, 3],
[4, 5, 6]])
np.sum(arr) # 21 全部求和(不指定 axis → 所有元素)
np.sum(arr, axis=0) # [5 7 9] 按列求和(每列纵向加总)
np.sum(arr, axis=1) # [6 15] 按行求和(每行横向加总)
记忆技巧:axis=0 沿"行"方向压扁 → 结果是每列的聚合;axis=1 沿"列"方向压扁 → 结果是每行的聚合。
一个更稳的口诀:结果数组的 shape 里,axis 那一位被"压掉"了:
(3, 4)配axis=0→(4,)(每列一个数)(3, 4)配axis=1→(3,)(每行一个数)
三维数组同理:np.sum(arr, axis=0) 把第 0 维压掉。
多维实战:5 位同学 × 3 门课
沿用贯穿案例:
scores = np.array([[90, 80, 85], # 同学1:语 数 英
[60, 70, 65],
[95, 88, 92],
[72, 65, 78],
[55, 60, 70]])
scores.mean(axis=1) # 每位同学平均分
# [85. 65. 91.66666667 71.66666667 61.66666667]
scores.mean(axis=0) # 每门课平均分
# [74.4 72.6 78. ] 语文 74.4,数学 72.6,英语 78
scores.max(axis=0) # 每门课最高分 [95 88 92]
scores.std(axis=1) # 每位同学成绩波动(标准差)
axis=1 求"每个人",axis=0 求"每门课"——这是聚合最重要的两个方向。
找出最值的位置:argmax / argmin
arr = np.array([3, 1, 4, 1, 5, 9, 2])
np.argmax(arr) # 5 最大值 9 在索引 5
np.argmin(arr) # 1 最小值 1 在索引 1
# 二维配合 axis:找每列/每行的最值位置
np.argmax(scores, axis=0) # [2 2 2] 每门课最高分在同学索引 2
np.argmax(scores, axis=1) # [0 2 2 2 2] 每位同学哪门课最高
💡
argmax/argmin返回**位置(索引)**而非值。机器学习里np.argmax(model(x))就是"预测的类别"——分类问题最常用的收尾动作。
其它实用统计
np.percentile(arr, 90) # 第 90 百分位数(90% 数据比它小)
np.percentile(arr, [25, 50, 75]) # 四分位数 Q1/Q2/Q3
np.ptp(arr) # 极差 = max - min
np.corrcoef(x, y) # 相关系数矩阵(两变量线性相关程度)
np.bincount(arr).argmax() # 众数(出现最多的值)
💡 百分位数是"分位数"的通用版:
np.percentile(data, 50)就是中位数。画箱线图、看数据分布都要它。
方法 vs 函数:arr.sum() 与 np.sum(arr) 等价
arr.sum() # 方法形式
np.sum(arr) # 函数形式 —— 完全等价
两者都行,只是写法不同。np.sum 这种函数形式可以传任意数组,方法形式更"面向对象"。选一种保持风格一致即可。
小结
| 函数 | 作用 | 忽略 NaN 版本 |
|---|---|---|
sum / mean |
和 / 平均 | nansum / nanmean |
max / min |
最大 / 最小 | nanmax / nanmin |
std / var |
标准差 / 方差 | nanstd |
median |
中位数 | nanmedian |
argmax / argmin |
最值位置 | — |
percentile |
百分位数 | nanpercentile |
- ⚠️
NaN会污染结果 → 用nan系列 - ⭐
axis=0按列、axis=1按行,压掉指定维度 argmax拿位置(索引),常用于分类预测arr.sum()和np.sum(arr)等价
下一章:不同形状的数组怎么直接运算(广播)。
上一篇:第 6 章 通用函数 | 下一篇:第 8 章 广播机制