NumPy 统计运算与矩阵逻辑学习笔记

掌握 NumPy 数组后,下一步就是利用数组完成统计分析与矩阵运算。均值、方差、标准化、缺失值处理和矩阵乘法,既是数据分析的基本功,也是机器学习中的高频操作。本文对这些知识进行一次精简复盘。

一、集中趋势:sum、mean 与 median

NumPy 内置了常用统计函数,不需要手写循环:

import numpy as np scores = np.array([60, 70, 80, 90]) print(scores.sum()) # 300 print(scores.mean()) # 75.0 print(np.median(scores)) # 75.0

其中,均值和中位数反映数据的集中趋势,但适用场景不同:

  • mean是算术平均值,会明显受到极端值影响;

  • median是排序后的中间值,对极端值更加稳健。

data = np.array([1, 2, 3, 4, 100]) print(data.mean()) # 22.0 print(np.median(data)) # 3.0

收入、房价等偏态数据通常更适合报告中位数。对空数组调用mean()会产生警告并返回nan,因此正式计算前应检查array.size

二、离散程度与极值

除了典型水平,还需要描述数据的波动范围:

scores = np.array([60, 70, 80, 90]) print(scores.var()) # 方差 125.0 print(scores.std()) # 标准差约 11.18 print(scores.min()) # 60 print(scores.max()) # 90 print(np.ptp(scores)) # 极差 30

方差是各数据与均值偏差平方的平均值,单位是原数据单位的平方;标准差是方差的平方根,与原数据单位一致,因此更容易解释:

assert np.isclose( scores.std(), np.sqrt(scores.var()), )

NumPy 的方差和标准差默认使用总体公式,即ddof=0,分母为N。估计样本方差或样本标准差时常使用ddof=1,分母变为N-1

population_std = scores.std(ddof=0) sample_std = scores.std(ddof=1)

比较 NumPy、pandas 或其他统计软件结果时,应先确认ddof设置是否一致。

三、axis:沿指定维度统计

二维数组可以整体统计,也可以按行或按列统计:

matrix = np.array([ [1, 2, 3], [4, 5, 6], ]) print(matrix.sum()) # 21 print(matrix.sum(axis=0)) # [5 7 9],每列求和 print(matrix.sum(axis=1)) # [ 6 15],每行求和

可以把axis理解为“被压缩掉的维度”:

  • axis=0:第 0 维消失,得到每列结果;

  • axis=1:第 1 维消失,得到每行结果。

同样的规则适用于mean()std()min()max()。不确定方向时,先查看输入和输出的shape,不要只靠记忆。

四、标准化与归一化

1. Z-score 标准化

Z-score 将数据转换为均值约为 0、标准差约为 1 的形式:

data = np.array([60, 70, 80, 90]) z_score = (data - data.mean()) / data.std() assert np.isclose(z_score.mean(), 0) assert np.isclose(z_score.std(), 1)

如果数组标准差为 0,说明所有元素相同,此时分母为 0,会得到无效结果,需要提前处理。

2. Min-Max 归一化

将每一行缩放到[0, 1]

data = np.array([ [1, 2, 3], [4, 5, 6], ]) row_min = data.min(axis=1, keepdims=True) row_max = data.max(axis=1, keepdims=True) normalized = ( (data - row_min) / (row_max - row_min) )

keepdims=True会保留被统计的维度,使结果形状为(2, 1),从而能够通过广播与原矩阵运算。若某一行最大值等于最小值,也会出现除零问题。

五、NaN 与缺失值统计

NumPy 通常使用np.nan表示浮点数组中的缺失值:

data = np.array([1.0, 2.0, np.nan, 4.0]) print(data.mean()) # nan print(data.sum()) # nan

NaN具有传染性,普通统计结果也会变成NaN。查找缺失值必须使用np.isnan()

mask = np.isnan(data) print(mask) print(data[~mask]) # 保留非缺失值

不能使用data == np.nan,因为NaN不等于任何值,包括它自己。

NumPy 提供了一组忽略缺失值的统计函数:

print(np.nanmean(data)) print(np.nanmedian(data)) print(np.nanstd(data)) print(np.nansum(data)) print(np.nanmin(data)) print(np.nanmax(data))

如果数组全部为NaN,某些函数仍会发出警告并返回NaN,因此不能把nanmean()理解为任何情况下都能得到有效结果。

六、删除与填充缺失值

删除一维数组中的缺失值,可以使用布尔索引:

clean = data[~np.isnan(data)]

也可以用均值、中位数或业务常量填充:

median = np.nanmedian(data) filled = np.where( np.isnan(data), median, data, )

np.where(condition, true_value, false_value)会根据条件逐元素选择结果。

缺失值策略没有固定答案:缺失比例很低时可以删除;偏态数据通常用中位数填充比均值更稳健;缺失本身具有业务含义时,可以增加缺失标记,而不是简单填 0。正式分析还应避免使用整份数据的统计量填充测试集,以免产生数据泄漏。

七、逐元素乘法与矩阵乘法

NumPy 中*@的含义完全不同:

A = np.array([ [1, 2], [3, 4], ]) B = np.array([ [5, 6], [7, 8], ]) print(A * B) # [[ 5 12] # [21 32]] print(A @ B) # [[19 22] # [43 50]]
  • A * B:对应位置逐元素相乘;

  • A @ B:按照线性代数规则做矩阵乘法。

二维数组中,A @ Bnp.matmul(A, B)等价,np.dot(A, B)也能得到相同结果,但高维行为存在差异。表达矩阵乘法时,@通常最直观。

八、矩阵乘法的形状规则

如果A的形状为(m, n)B的形状为(n, p),那么:

A @ B 的结果形状为 (m, p)

核心条件是A的列数等于B的行数:

A = np.array([[1, 2, 3]]) # shape: (1, 3) B = np.array([[1], [2], [3]]) # shape: (3, 1) result = A @ B print(result) # [[14]] print(result.shape) # (1, 1)

矩阵乘法报错时,应按以下顺序排查:

  1. 打印A.shapeB.shape

  2. 检查A.shape[-1]是否等于B.shape[-2]

  3. 判断需求究竟是逐元素乘法还是矩阵乘法;

  4. 只有数学含义确实需要时,才使用转置.Treshape()调整形状。

不能仅为了消除错误而随意转置数组,否则代码虽然能运行,计算含义却可能错误。

九、真实数据分析的基本流程

对 CSV 等真实数据进行统计时,可以遵循以下流程:

  1. 使用csv、pandas 等工具正确解析文件;

  2. 将需要计算的数值列转换为 NumPy 数组;

  3. 无法转换或为空的值记为np.nan

  4. 使用np.isnan()统计缺失情况;

  5. 使用nanmean()nanmedian()等函数计算描述性统计;

  6. 根据业务和建模需求决定删除、填充或保留缺失标记;

  7. 检查数组的shapedtype和结果范围。

读取 CSV 时不应简单依赖split(","),因为字段本身可能包含逗号和引号。应使用标准库csv或 pandas 等规范解析工具。

十、常见错误总结

常见错误正确做法
用均值描述含极端值的偏态数据同时查看中位数
不区分总体和样本标准差明确设置ddof
混淆axis=0axis=1查看统计后结果的形状
对含NaN的数组直接mean()使用nanmean()或先处理缺失
使用array == np.nan使用np.isnan(array)
忽略标准化分母为 0提前检查标准差或极差
使用*做矩阵乘法使用@
为了通过运算随意转置矩阵先确认数学含义和形状规则

总结

NumPy 统计与矩阵运算的核心,是同时理解“数值含义”和“数组形状”:

  1. 均值容易受极端值影响,中位数更加稳健;

  2. 标准差是方差的平方根,样本统计要关注ddof

  3. axis=0得到每列结果,axis=1得到每行结果;

  4. keepdims=True可以保留维度,方便后续广播;

  5. 查找缺失值使用np.isnan(),忽略缺失的统计使用nan*函数;

  6. *是逐元素乘法,@是矩阵乘法;

  7. 矩阵乘法要求前一个数组的末维与后一个数组的倒数第二维匹配;

  8. 统计与矩阵代码出现异常时,先检查shapedtype、缺失值和数值范围。

建议通过成绩统计、逐行归一化、缺失值填充和二维矩阵乘法等案例反复练习,逐渐形成“先确认数据含义,再确认数组形状,最后执行计算”的习惯。