为何pd.corr与np.corrcoef的相关性计算结果存在差异?
Pandas与Numpy相关性计算结果差异原因分析
问题复现
在使用Pandas和Numpy计算数据相关性时,出现部分结果不一致的情况,以下是完整的复现代码与结果:
示例数据代码
import numpy as np import pandas as pd import os df = pd.DataFrame( {"name": ["a", "b", "c", "d", "e", "f"], "type": [float, float, float, float, float, float], "value": [2.121,np.nan,21.131,30.4242,100.424, 22.4341], "obs": [44, 55, 22, 77, 88, 33], "num": [66, 23, 62, 63, 23, 12]} )
相关性计算代码
# Pandas 计算方式 pandas_corr = df.corr() # Numpy 计算方式 numeric_only_df = df.select_dtypes("number").dropna() numpy_corr = pd.DataFrame(np.corrcoef(numeric_only_df, rowvar=False), columns=numeric_only_df.columns, index=numeric_only_df.columns)
计算结果
Pandas 结果
value obs num value 1.000000 0.732365 -0.524068 obs 0.732365 1.000000 -0.138357 num -0.524068 -0.138357 1.000000
Numpy 结果
value obs num value 1.000000 0.732365 -0.524068 obs 0.732365 1.000000 -0.134928 num -0.524068 -0.134928 1.000000
差异原因
核心差异来自缺失值的处理逻辑不同:
- Pandas
corr()默认采用「成对删除」(pairwise deletion):计算任意两个变量的相关性时,仅删除这两个变量中存在缺失值的行,其他变量的缺失不影响当前变量对的计算。比如计算obs和num的相关性时,这两列没有缺失值,所以会用全部6行数据计算。 - 你的Numpy处理采用「列表删除」(listwise deletion):先通过
dropna()删除所有包含缺失值的行(即删除value列有NaN的第2行),再用剩下的5行数据计算所有变量的相关性。
验证计算
以obs和num的相关性为例:
- Pandas使用的6行数据:
obs: [44,55,22,77,88,33]num: [66,23,62,63,23,12]
计算得皮尔逊相关系数为-0.138357,与Pandas结果一致。 - Numpy使用的5行数据(删除第2行):
obs: [44,22,77,88,33]num: [66,62,63,23,12]
计算得皮尔逊相关系数为-0.134928,与Numpy结果一致。
如何让结果一致
如果想让Numpy的计算结果和Pandas一致,需要对每一对变量单独进行缺失值处理(成对删除),再计算相关性,而不是先整体删除所有含缺失的行。
内容的提问来源于stack exchange,提问作者user21060710
相关产品推荐
相关产品推荐

