导读:本期聚焦于Canve创作的《Python怎么计算相关系数?corr()皮尔逊与斯皮尔曼相关性解析》,敬请观看详情。当两个变量的线性关系被少数异常值扭曲时,皮尔逊系数常常给出误导性结论,而斯皮尔曼基于秩排序,对离群点更稳健。这篇文章从pandas的corr()方法入手,演示如何一行代码分别计算皮尔逊与斯皮尔曼相关系数,并通过实际数据对比两者的数值差异与适用场景。内容覆盖相关矩阵解读、显著性检验以及热力图可视化,帮助读者在相关性分析中避免盲目套用默认参数。

相关系数用来衡量两个变量之间线性或单调关系的强弱,取值范围从-1到1。很多初学者在调用pandas的corr()时只会使用默认参数,却忽略了皮尔逊与斯皮尔曼背后的假设差异。前者评估线性相关,后者评估单调相关,选错方法可能让结论完全失真。

Python怎么计算相关系数?corr()皮尔逊与斯皮尔曼相关性解析

皮尔逊与斯皮尔曼的差异到底在哪里

皮尔逊相关系数衡量的是两个连续变量之间的线性关系强度,公式基于原始数据的协方差除以各自标准差的乘积。它要求变量近似服从正态分布,且对异常值极其敏感。例如一组房价数据中混入一个录入错误的天价极值,皮尔逊系数可能被拉低或拉高,干扰你对真实趋势的判断。

斯皮尔曼相关系数则先对每个变量的数据进行排序,用排名值替代原始数值,再对排名值计算皮尔逊公式。因此它衡量的是两个变量之间单调关系的强度——只要一个变量增加时另一个变量总是增加(或总是减少),不论关系是直线还是曲线,斯皮尔曼系数都接近1或-1。这种基于秩的方法对异常值不敏感,也不要求数据服从正态分布,非常适合有序分类变量或存在明显离群点的场景。

两者的适用条件可以总结为:皮尔逊适合满足线性、连续、无显著离群点的数据;斯皮尔曼适合非线性但方向一致、含有离群点、或者数据本身就是等级顺序的情况。如果数据中存在强非线性关系,比如y=x^2在[0,1]区间内,皮尔逊系数可能只有0.9左右,而斯皮尔曼系数则接近1。

使用Pandas的corr()一行代码计算

Pandas的DataFrame对象自带corr()方法,通过method参数可以切换不同的相关系数类型。默认method=‘pearson’,也可以传入‘spearman’或‘kendall’。下面用一份模拟的考试成绩数据来演示如何同时计算两种系数。

import pandas as pd
import numpy as np

# 构造模拟数据:数学成绩、英语成绩和平时学习时长(小时)
data = {
    'math_score': [85, 90, 78, 92, 88, 76, 95, 42, 89, 91],
    'english_score': [82, 85, 75, 88, 86, 72, 90, 80, 87, 93],
    'study_hours': [3.5, 4.0, 2.5, 4.2, 3.8, 2.0, 4.5, 1.5, 4.0, 4.3]
}
df = pd.DataFrame(data)
print(df.head())

调用corr()默认返回所有数值列两两之间的皮尔逊相关矩阵。下面的代码同时计算皮尔逊和斯皮尔曼相关矩阵,并打印输出。

pearson_corr = df.corr(method='pearson')
spearman_corr = df.corr(method='spearman')

print("皮尔逊相关矩阵:")
print(pearson_corr)
print("\n斯皮尔曼相关矩阵:")
print(spearman_corr)

从输出可以看到,每一行每一列的交点就是两个变量的相关系数。矩阵是对称的,对角线永远是1.0。上面模拟数据中math_score里故意放入了一个42分的低值,使得皮尔逊系数可能被拉低;而斯皮尔曼因为只关心排名,42分排名最后,不会像皮尔逊那样受到离群距离的严重影响。

如果你只关心某一对变量的相关系数,可以使用df['math_score'].corr(df['english_score'], method='pearson')的方式直接计算标量值。但corr()返回矩阵更方便后续画热力图。

实际分析中的关键注意点

相关系数大小不能直接说明关系显著。比如皮尔逊系数0.3在样本量为30和样本量为300时,统计显著性完全不同。Python中需要借助scipy.stats的pearsonr或spearmanr来计算p值,判断相关是否显著。下面的代码演示了对数学和英语成绩进行皮尔逊检验。

from scipy.stats import pearsonr, spearmanr

r_p, p_p = pearsonr(df['math_score'], df['english_score'])
r_s, p_s = spearmanr(df['math_score'], df['english_score'])

print(f"皮尔逊 r={r_p:.3f}, p={p_p:.4f}")
print(f"斯皮尔曼 r={r_s:.3f}, p={p_s:.4f}")

当p值小于0.05时,可以认为相关系数在统计上显著不为零。此外,即使相关系数很高,也不能直接推断因果关系,除非有实验设计或领域知识支撑。相关系数是对称的,交换两个变量位置结果不变。

数据预处理同样关键。corr()默认忽略缺失值,但如果某一列包含非数值类型,需要先转换或排除。在分析之前,建议检查数据的分布,使用seaborn的pairplot或热力图可以帮助直观判断。下面给出用seaborn绘制相关矩阵热力图的代码。

import matplotlib.pyplot as plt
import seaborn as sns

plt.figure(figsize=(8, 6))
sns.heatmap(pearson_corr, annot=True, cmap='coolwarm', vmin=-1, vmax=1)
plt.title('Pearson Correlation Heatmap')
plt.show()

热力图中颜色越深表示相关性越强,标注的数字可以直接读取数值。当数据中存在非线性关系时,观察斯皮尔曼热力图与皮尔逊热力图的差异,能够发现被线性假设掩盖的单调关联。

理解corr()的底层实现有助于避免误解。皮尔逊计算的是cov(x,y)/(std(x)*std(y)),斯皮尔曼则先对每列做rank()变换再调用皮尔逊公式。如果数据中存在并列值,rank会默认采用平均排名,这可能导致斯皮尔曼系数略有偏差,但通常影响很小。Pandas内部使用numpy的相关系数计算,性能足以处理中等规模数据。

总结来看,进行相关性分析时应先明确研究目的是线性关系还是单调关系,然后选择对应的method参数。遇到异常值或非正态数据时优先考虑斯皮尔曼;只有确认数据满足线性假设时才使用默认的皮尔逊。配合显著性检验和可视化,才能得出可靠结论。

Python相关系数皮尔逊斯皮尔曼修改时间:2026-09-17 07:16:52

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/0917/58362.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。