如何从两列Pandas DataFrame计算Pearson相关系数并生成热图与二维直方图?
解决方案
一、计算类别对Pearson相关系数并绘制热图
先把原始数据转成宽格式(每个类别作为一列,行对应该类别下的响应值),再计算列间的Pearson相关系数,最后用热图可视化结果。
import pandas as pd import seaborn as sns import matplotlib.pyplot as plt # 假设原始数据存储在df中 # 转换为宽格式:每个CATEGORY作为一列,值为对应的RESPONSE wide_df = df.pivot(columns='CATEGORY', values='RESPONSE') # 计算所有类别对的Pearson相关系数矩阵 corr_matrix = wide_df.corr(method='pearson') # 绘制热图 plt.figure(figsize=(12, 10)) # 间隔显示标签避免400个类别导致的拥挤问题 sns.heatmap(corr_matrix, cmap='coolwarm', xticklabels=50, yticklabels=50) plt.title('Pearson Correlation Between Categories') # 保存图片,bbox_inches='tight'避免标签被裁剪 plt.savefig('category_correlation_heatmap.png', dpi=300, bbox_inches='tight') plt.close()
说明:
pivot会自动处理同一类别下的多个响应值,不同类别样本数不一致时用NaN填充,计算相关系数时会自动忽略缺失值- 可根据实际需求调整
xticklabels和yticklabels的间隔数值,优化热图可读性
二、生成RESPONSE-vs-CATEGORY二维直方图及分箱后相关系数计算
1. 生成可保存的二维直方图
先对RESPONSE分10个0.1宽度的区间,再用交叉表生成二维频数矩阵,最后用热图展示直方图:
# 对RESPONSE分箱,生成带标签的区间列 df['RESPONSE_BIN'] = pd.cut( df['RESPONSE'], bins=10, labels=['0.0-0.1', '0.1-0.2', '0.2-0.3', '0.3-0.4', '0.4-0.5', '0.5-0.6', '0.6-0.7', '0.7-0.8', '0.8-0.9', '0.9-1.0'] ) # 生成二维直方图的频数矩阵(行:CATEGORY,列:RESPONSE区间) hist_2d = pd.crosstab(df['CATEGORY'], df['RESPONSE_BIN']) # 可视化二维直方图 plt.figure(figsize=(10, 12)) sns.heatmap(hist_2d, cmap='Blues', annot=False, fmt='d', cbar_kws={'label': 'Count'}) plt.xlabel('Response Interval') plt.ylabel('Category') plt.title('2D Histogram: Category vs. Binned Response') plt.savefig('response_category_2d_histogram.png', dpi=300, bbox_inches='tight') plt.close()
2. 基于分箱后的数据计算Pearson相关系数
场景1:类别对之间基于响应区间频数的相关系数
计算不同类别在响应区间上的频数分布的Pearson相关:
# 计算分箱后类别对的Pearson相关系数矩阵 corr_matrix_binned = hist_2d.corr(method='pearson') # 可选:绘制分箱后的相关系数热图 plt.figure(figsize=(12, 10)) sns.heatmap(corr_matrix_binned, cmap='coolwarm', xticklabels=50, yticklabels=50) plt.title('Pearson Correlation Between Categories (Binned Response)') plt.savefig('category_correlation_binned_heatmap.png', dpi=300, bbox_inches='tight') plt.close()
场景2:CATEGORY与分箱后RESPONSE的相关系数
若需要计算类别与分箱响应值的直接相关,可先将分箱标签转为数值(如区间中值)再计算:
# 将分箱标签转换为区间中值,便于计算相关系数 df['RESPONSE_BIN_MID'] = df['RESPONSE_BIN'].apply(lambda x: float(x.split('-')[0]) + 0.05) # 计算两者的Pearson相关系数 binned_corr = df[['CATEGORY', 'RESPONSE_BIN_MID']].corr(method='pearson') print(binned_corr)
内容的提问来源于stack exchange,提问作者Emil Frlez
相关产品推荐
相关产品推荐

