np.cov()默认按行视为变量(rowvar=True),与常规列变量习惯相反,易致维度错误;应显式设rowvar=False或转置data.T,且需预处理缺失值。

协方差矩阵用 np.cov() 但默认按行还是列?
np.cov() 默认把**每一行当作一个变量(特征)**,列当作观测样本——这和大多数统计建模习惯(列是变量、行是样本)相反。容易导致结果维度错乱或数值反直觉。
常见错误现象:传入 shape 为 (100, 5) 的数据(100 个样本、5 个特征),却得到 100×100 的协方差矩阵,而不是预期的 5×5。
- 加参数
rowvar=False显式指定“列是变量”,这是最稳妥的做法 - 或者先转置:
np.cov(data.T),效果等价但可读性差 - 注意:若数据含缺失值,
np.cov()默认会报错;需先用np.nan_to_num()或用np.ma.masked_invalid()处理
相关系数矩阵必须用 np.corrcoef() 吗?
不用。虽然 np.corrcoef() 是专用函数,但它底层就是对 np.cov() 结果做标准化(除以标准差乘积),且同样默认 rowvar=True。
更可控的做法是:先算协方差矩阵,再手动归一化。这样能避开隐式行为,也方便调试:
立即学习“Python免费学习笔记(深入)”;
import numpy as np cov = np.cov(data, rowvar=False) stds = np.sqrt(np.diag(cov)) corr = cov / np.outer(stds, stds)
这个写法和 np.corrcoef(data, rowvar=False) 等价,但显式暴露了归一化逻辑,避免因 stds 为 0(某列全相同)导致除零警告——你可以在除之前加判断。
单变量间皮尔逊相关系数别调用 np.corrcoef() 返回整个矩阵
如果只要两个一维数组 x 和 y 的相关系数,直接取 np.corrcoef(x, y)[0, 1] 很不直观,还多算了一半矩阵。
推荐用 scipy.stats.pearsonr(),它只返回标量和 p 值:
from scipy.stats import pearsonr r, p = pearsonr(x, y)
如果你坚持纯 NumPy,可手写公式(更轻量、无依赖):
def pearson_r(x, y):
xm, ym = x - x.mean(), y - y.mean()
return (xm @ ym) / np.sqrt((xm @ xm) * (ym @ ym))注意:该实现不处理 NaN,也不校正自由度,但对干净数据足够快且明确。
协方差/相关系数结果为复数?那是数据类型惹的祸
当输入数组 dtype 是 complex 或含复数时,np.cov() 和 np.corrcoef() 会返回复数结果——即使你本意只是处理实数。
排查路径:
- 检查原始数据:
data.dtype是否意外为complex64或complex128 - 检查是否从 pandas DataFrame 读入后未清理:某些操作(如空值插补 + 类型推断)可能悄悄转成
object,再转np.array时变成complex - 强制转实数:
data = np.asarray(data).real,但要确认丢弃虚部是否合理
这种问题往往在数据管道下游才暴露,建议在计算前加一句 assert np.isrealobj(data) 做快速守卫。


















