
本文介绍如何高效计算二维列表中每列(相同索引位置)所有非零元素的平均值,使用 numpy 实现一行核心代码即可完成垂直方向的求和与非零计数,并自动广播除法。
本文介绍如何高效计算二维列表中每列(相同索引位置)所有非零元素的平均值,使用 numpy 实现一行核心代码即可完成垂直方向的求和与非零计数,并自动广播除法。
在处理矩阵式数据(如多用户对同一组项目的评分)时,常需按列聚合——即对每个特征维度(对应索引位置)统计其非零观测值的均值。原始嵌套列表结构天然适合“列优先”操作,但纯 Python 循环易出错(如题中误将行列遍历混淆为扁平化遍历),且性能低下。
正确思路是:按列(axis=0)对所有行同位置元素进行操作。NumPy 提供了简洁、向量化、高性能的解决方案:
import numpy as np
rating_values = [
[0, 5, -3, 5, 0, 0],
[-3, 0, 1, 0, 5, 0],
[1, 0, 5, 0, -5, 0],
[-3, 0, 3, 0, 0, 5]
]
# 转换为 NumPy 数组
x = np.array(rating_values)
# 核心逻辑:列方向求和 / 列方向非零元素个数
y = np.sum(x, axis=0) / np.sum(x != 0, axis=0)
# 自动处理除零:当某列全为 0 时,np.sum(x != 0, axis=0) 为 0 → 结果为 inf/NaN;
# 但本例中第4列(索引4)含 [0,5,-5,0],非零数为2,均值为0;第5列[0,0,0,5]均值为5.0
# 如需严格规避除零,可添加掩码:
# counts = np.sum(x != 0, axis=0)
# y = np.divide(np.sum(x, axis=0), counts, out=np.zeros_like(counts, dtype=float), where=counts!=0)
print(y.round(6))
# 输出: [-1.666667 5. 1.5 5. 0. 5. ]
✅ 关键解析:
- axis=0 表示沿行方向压缩,即对每一列内所有行元素运算;
- x != 0 返回布尔数组,np.sum(..., axis=0) 对每列统计 True(即非零)个数;
- NumPy 支持向量间逐元素除法,无需显式循环。
⚠️ 注意事项:
- 若某列全为 0,np.sum(x != 0, axis=0) 结果为 0,直接除法会触发 RuntimeWarning 并生成 inf 或 nan。生产环境建议使用 np.divide 配合 where 参数或手动填充默认值(如 0.0);
- 纯 Python 实现(如用 zip(*rating_values) 转置)虽可行,但代码冗长且无向量化优势,不推荐用于中大规模数据。
综上,NumPy 不仅以单行代码精准达成目标,更通过底层优化保障效率与可读性——这是科学计算与数据预处理的标准实践。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!











