pandas agg后直方图按记录计数而非列值,需绘制并排对比图
解决直方图计数权重与疫情前后并排展示问题
问题描述
想要绘制基于年龄组的直方图,但现有代码存在两个问题:
- 每条记录被计为1,未使用
PATIENT_UNIQUE_COUNT列的实际数值作为计数权重 - 无法将疫情前后(BEFORE/AFTER)的直方图并排展示
现有代码:
df5=df.groupby(["PANDEMIC","PATIENT_AGE_GRP"]).agg( {"PATIENT_ID": pd.Series.nunique}).rename(columns={'PATIENT_ID':'PATIENT_UNIQUE_COUNT'}) sns.histplot(x='PATIENT_AGE_GRP', data=df5, kde=True, hue='PANDEMIC') plt.show()
处理后的数据结构:
PATIENT_UNIQUE_COUNT PANDEMIC PATIENT_AGE_GRP AFTER 15-19 14 20-24 21 25-29 58 30-34 90 35-39 156 40-44 194 45-49 266 50-54 369 55-59 535 60-64 660 65-69 829 70-74 823 75-79 713 80-84 657 85-89 576 90+ 595 <1 1 NA 5 BEFORE 15-19 13 20-24 14 25-29 41 30-34 56 35-39 144 40-44 179 45-49 279 50-54 466 55-59 758 60-64 873 65-69 929 70-74 890 75-79 860 80-84 789 85-89 726 90+ 757 NA 11
解决方案
1. 先处理数据格式
当前df5是多级索引结构,得先把索引转成普通列,不然Seaborn没法正确读取分组信息:
df5 = df5.reset_index()
2. 实现权重计数+并排展示
用FacetGrid可以直接把疫情前后的数据拆分成两个并排子图,再通过weight参数指定用PATIENT_UNIQUE_COUNT的数值来计数:
import seaborn as sns import matplotlib.pyplot as plt # 重置索引 df5 = df5.reset_index() # 创建分栏网格,按疫情阶段拆分 g = sns.FacetGrid(df5, col="PANDEMIC") # 在每个子图绘制直方图,指定计数权重 g.map(sns.histplot, "PATIENT_AGE_GRP", weights="PATIENT_UNIQUE_COUNT", kde=True) # 调整布局和标题 g.set_titles("{col_name} Pandemic") plt.tight_layout() plt.show()
如果觉得直方图对分类年龄组的展示不够直观,也可以用条形图替代(更适合看具体数值):
# 重置索引后用catplot绘制并排条形图 sns.catplot(x='PATIENT_AGE_GRP', y='PATIENT_UNIQUE_COUNT', col='PANDEMIC', kind='bar', data=df5, height=6, aspect=1) plt.xticks(rotation=45) plt.tight_layout() plt.show()
关键说明
weights="PATIENT_UNIQUE_COUNT":让图表不再把每一行数据算成1个,而是用该列的数值统计每个年龄组的实际人数col="PANDEMIC":自动按疫情前后拆分数据,生成两个并排的子图- 年龄组属于分类变量,用条形图替代直方图能更清晰地展示各年龄组的具体人数,可读性更强
内容的提问来源于stack exchange,提问作者ladskjflasdkjfl
相关产品推荐
相关产品推荐

