如何为含稀疏NaN数据的seaborn PairGrid添加相关系数标注
报错原因
scipy.stats.pearsonr 原生不支持自动跳过NaN值,传入含缺失值的数组就会抛出ValueError: array must not contain infs or NaNs。
seaborn内置的散点图、KDE绘图逻辑会自动丢弃对应轴缺失的样本,但自定义的相关系数计算函数没有做缺失值过滤,传入全量含NaN的列就触发了报错。另外要注意不要把字符串类型的group列传入PairGrid,否则会出现类型错误。
修改方案
调整自定义的corr_func函数,计算前先成对剔除两个变量中存在缺失值的样本,逻辑和seaborn内置绘图的缺失值处理保持一致,同时增加有效样本数判断,避免样本量不足时的计算错误。
完整可运行代码如下:
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt from scipy import stats def corr_func(x, y, **kws): # 成对过滤两个变量的缺失值 valid_pair = ~(x.isna() | y.isna()) x_clean, y_clean = x[valid_pair], y[valid_pair] # 有效样本不足2时无法计算相关系数,直接跳过 if len(x_clean) < 2: return r, _ = stats.pearsonr(x_clean, y_clean) ax = plt.gca() ax.annotate(f"{r:.2f}", xy=(0.3, 0.45), xycoords=ax.transAxes, size=30) def plot_corrplot(df): # 仅提取数值特征列传入PairGrid,排除字符串类型的group列 feature_cols = df.columns.drop("group") g = sns.PairGrid(df[feature_cols], diag_sharey=False, corner=False) g.map_lower(sns.scatterplot, s=10, color="black") g.map_diag(sns.kdeplot, color="grey") g.map_upper(corr_func) plt.show() # 读取剪贴板数据运行 df = pd.read_clipboard(sep=",") plot_corrplot(df)
关键说明
- 采用成对删除(pairwise deletion)逻辑处理缺失值:计算每一对变量的相关系数时,仅剔除这两个变量存在缺失的样本,和散点图展示的样本范围完全匹配,不会出现计算结果和可视化内容不对应的问题
- 增加样本量校验:如果两个变量的共同有效样本不足2个(比如完全没有重叠观测的变量对),直接跳过标注,不会触发计算报错
- 自动适配稀疏数据场景:即使不同变量的有效样本来自不同分组,只要两个变量存在共同的非缺失观测,就可以正常计算相关系数
内容的提问来源于stack exchange,提问作者sirmanleypower
相关产品推荐
相关产品推荐

