Python中计算两DataFrame相关性corrwith返回NaN如何解决
问题背景
我有一个存储岗位领域画像的DataFrame,结构示例如下:
我基于用户输入生成了对应的用户DataFrame,结构示例如下:
当前需要计算用户XYZ的个人画像与云计算、数据科学方向岗位画像的相关性,最初尝试使用如下代码实现:
job_df.corrwith(user_df)
但代码执行后返回的结果为NaN,以下是解决方案:
问题原因
corrwith返回NaN基本是三类问题导致:
- 默认按列对齐计算,和「逐行匹配岗位与用户计算相关性」的需求不匹配
- 两个DataFrame的列(技能标签)、索引没有对齐,存在列名不一致、行数不匹配的问题
- 存在非数值类型字段、某行/列数值完全一致(标准差为0,导致皮尔逊相关系数分母为0)的异常数据
解决步骤
1. 先对齐字段与索引
首先提取两个DataFrame共有的技能列,避免两边列名不统一(比如大小写差异、冗余字段)导致匹配失败,再把用户的画像数据对齐到岗位表的索引维度:
# 提取两边共有的技能标签列 common_skills = job_df.columns.intersection(user_df.columns) job_aligned = job_df[common_skills].astype(float) # 提取用户XYZ的画像数据,转成数值格式 user_series = user_df.loc["XYZ", common_skills].astype(float)
2. 逐行计算岗位与用户的相关性
corrwith默认参数axis=0是按列计算,要逐行计算每个岗位和用户的相关性,直接用apply遍历岗位行计算即可,写法稳定不会因为索引对齐出问题:
corr_result = job_aligned.apply(lambda row: row.corr(user_series), axis=1)
如果要直接用corrwith方法,需要先把用户数据广播到和岗位表相同行数、对齐索引,再指定axis=1按行计算:
user_aligned = user_df.loc[["XYZ"], common_skills].reindex(job_aligned.index, method="ffill").astype(float) corr_result = job_aligned.corrwith(user_aligned, axis=1)
3. 异常数据排查
如果执行完上面步骤还是有NaN,按下面的方法排查:
- 检查数据类型:确保所有参与计算的字段都是数值型,没有被识别为字符串(比如"熟练""掌握"这类文本标签要提前转成数值权重)
- 检查标准差:如果某一行所有数值完全相同,标准差为0,皮尔逊相关系数会返回NaN,可以用下面代码排查:
# 检查岗位每行的标准差 print(job_aligned.std(axis=1)) # 检查用户画像的标准差 print(user_series.std())
如果确实存在标准差为0的情况,可以更换相关系数计算方法(比如指定method="spearman"用斯皮尔曼相关),或者先修正异常的画像数据。
完整可运行示例
import pandas as pd # 模拟岗位画像表 job_df = pd.DataFrame( [[0.8, 0.9, 0.3, 0.2], [0.9, 0.2, 0.9, 0.8]], index=["云计算", "数据科学"], columns=["Python", "Linux", "SQL", "机器学习"] ) # 模拟用户画像表 user_df = pd.DataFrame( [[0.7, 0.8, 0.4, 0.3]], index=["XYZ"], columns=["Python", "Linux", "SQL", "机器学习"] ) # 对齐处理 common_skills = job_df.columns.intersection(user_df.columns) job_aligned = job_df[common_skills].astype(float) user_series = user_df.loc["XYZ", common_skills].astype(float) # 计算相关性 corr_result = job_aligned.apply(lambda x: x.corr(user_series), axis=1) print(corr_result)
执行后会直接输出两个岗位和用户XYZ的相关性得分,不会返回NaN。
内容的提问来源于stack exchange,提问作者ku11
相关产品推荐
相关产品推荐

