
本文介绍如何用一行简洁的 numpy 代码识别并剔除数组中所有方差为零(即所有非 nan 值完全相同)的列,同时兼容含 nan 的数据。
在数据预处理中,零方差特征(如全为同一常数、或除 NaN 外全部相同)通常不具备区分能力,应被移除以提升模型效率与稳定性。NumPy 提供了 np.var() 函数,默认会将 NaN 视为缺失值并导致整列方差为 nan;但直接使用 np.var(X, axis=0) != 0 会因 NaN 比较返回 False,从而错误丢弃含 NaN 的列——这正是需特别注意的关键点。
✅ 正确做法是:先显式忽略 NaN 计算方差,再筛选非零方差列。推荐使用 np.nanvar()(NumPy ≥ 1.10):
import numpy as np
X = np.array([[1, 10, np.nan, 0],
[2, 10, np.nan, 0],
[3, 10, np.nan, 0]])
# ✅ 安全剔除零方差列(自动跳过 NaN)
mask = np.nanvar(X, axis=0) != 0 # 返回布尔数组:[True, False, False, False]
X_filtered = X[:, mask]
print(X_filtered)
# 输出:
# [[ 1. nan]
# [ 2. nan]
# [ 3. nan]]⚠️ 注意事项:
- np.var() 在含 NaN 时返回 nan,而 nan != 0 为 False,会导致本该保留的列(如第1列 [10,10,10])被误删;
- np.nanvar() 自动沿指定轴忽略 NaN 计算方差,对全 NaN 列返回 nan,此时建议额外处理(例如设 nanvar(..., ddof=0) 并用 np.isfinite() 过滤);
- 若需同时剔除全 NaN 列、全零列和零方差列,可合并布尔掩码:
mask = (
~np.all(np.isnan(X), axis=0) & # 非全 NaN
~np.all(X == 0, axis=0) & # 非全零
np.nanvar(X, axis=0) != 0 # 非零方差(忽略 NaN)
)
X = X[:, mask]总结:np.nanvar(X, axis=0) != 0 是剔除零方差列最简洁、鲁棒且符合数据科学实践的标准方案,务必优先替代原始 np.var() 调用。










