Scipy与Pandas计算Spearman相关系数结果不一致问题
问题与代码输出
print(n1) print(n2) print(type(n1), type(n2)) print(scipy.stats.spearmanr(n1, n2)) print(n1.corr(n2, method="spearman")) # 输出结果: 0 2317.0 1 2293.0 2 1190.0 3 972.0 4 1391.0 Name: r6000, dtype: float64 0.0 2317.0 1.0 2293.0 3.0 1190.0 4.0 972.0 5.0 1391.0 Name: 6000, dtype: float64 <class 'pandas.core.series.Series'> <class 'pandas.core.series.Series'> SpearmanrResult(correlation=0.9999999999999999, pvalue=1.4042654220543672e-24) 0.7999999999999999
问题:使用Scipy的spearmanr方法与Pandas的corr方法(method="spearman")计算两组Pandas Series的Spearman相关系数时,结果差异显著,求分析原因及解决方法。
原因分析
核心差异来自数据匹配逻辑的不同:
- Pandas的
corr方法会自动按索引对齐数据:两个Series只有0、1、3、4这4个共同索引,计算时只保留这些索引对应的元素。对应的数据是n1的[2317,2293,972,1391]和n2的[2317,2293,1190,972],这组数据的Spearman相关系数约为0.8。 - Scipy的
spearmanr完全忽略索引,直接按元素位置一一对应计算:把n1的5个元素和n2的5个元素按顺序配对,两组数据完全正相关,因此系数接近1。
解决方法
根据你的需求选择对应方案:
想和Pandas逻辑一致(按索引对齐计算):
先对两个Series做索引对齐,再用Scipy计算:aligned_n1, aligned_n2 = n1.align(n2, join='inner') scipy.stats.spearmanr(aligned_n1, aligned_n2)想和Scipy逻辑一致(按位置对应计算):
在Pandas中忽略索引,直接用元素值计算:# 方案1:重置索引后计算 n1.corr(n2.reset_index(drop=True), method="spearman") # 方案2:直接使用底层数值数组 pd.Series(n1.values).corr(pd.Series(n2.values), method="spearman")
内容的提问来源于stack exchange,提问作者Blaze
相关产品推荐
相关产品推荐

