如何用Pandas按字符串列分组生成流失率DataFrame绘制Seaborn柱状图
解决按ageRange计算Attrition流失率并转为DataFrame的问题
方法一:修正现有逻辑转成DataFrame
你当前的计算逻辑是对的,但直接运算后得到的是Series,只需用reset_index()就能转成标准DataFrame,再重命名列名即可:
import pandas as pd Data_Hr = {"Age": [41,49,37,33,27], "Attrition": ["Yes", "No", "Yes", "No", "No"], "ageRange":["40-45","45-50","35-40","30-35","25-30"]} df = pd.DataFrame(Data_Hr) # 计算流失率(Yes占比),转成DataFrame并补全缺失值 attrition_rate = (df[df.Attrition == 'Yes']['ageRange'].value_counts() / df['ageRange'].value_counts() * 100).reset_index() attrition_rate.columns = ['ageRange', 'Attrition_Rate(%)'] # 没有Yes记录的年龄段会显示NaN,这里填充为0 attrition_rate['Attrition_Rate(%)'] = attrition_rate['Attrition_Rate(%)'].fillna(0)
方法二:用groupby更直观计算
用groupby按ageRange分组,直接统计每组的总人数和Yes人数,再计算占比,逻辑更清晰,且直接生成DataFrame:
# 分组统计+计算流失率 attrition_df = df.groupby('ageRange').agg( total_count=('Attrition', 'count'), yes_count=('Attrition', lambda x: (x == 'Yes').sum()) ).assign(Attrition_Rate=lambda x: (x['yes_count']/x['total_count'])*100).reset_index() # 保留需要的列 attrition_df = attrition_df[['ageRange', 'Attrition_Rate']]
用Seaborn绘制流失率柱状图
拿到整理好的DataFrame后,直接用barplot生成图表:
import seaborn as sns import matplotlib.pyplot as plt # 设置绘图风格 sns.set_style("whitegrid") # 绘制柱状图 plt.figure(figsize=(8, 5)) sns.barplot(data=attrition_df, x='ageRange', y='Attrition_Rate') # 添加标题和标签 plt.title('Attrition Rate by Age Range') plt.xlabel('Age Range') plt.ylabel('Attrition Rate (%)') # 给柱子添加数值标签(可选) for p in plt.gca().patches: height = p.get_height() plt.gca().text(p.get_x() + p.get_width()/2., height, f'{height:.1f}%', ha='center', va='bottom') plt.show()
其他绘制流失率的方法
- Pandas内置绘图:不用Seaborn的话,直接用DataFrame的
plot.bar()也能快速出图:
attrition_df.plot.bar(x='ageRange', y='Attrition_Rate', figsize=(8,5), title='Attrition Rate by Age Range') plt.ylabel('Attrition Rate (%)') plt.show()
- 堆叠柱状图:如果想同时展示各年龄段的总人数和流失/留存分布,可以画堆叠图:
stack_df = df.groupby(['ageRange', 'Attrition']).size().unstack(fill_value=0) stack_df.plot.bar(stacked=True, figsize=(8,5), title='Attrition Distribution by Age Range') plt.ylabel('Number of Employees') plt.show()
内容的提问来源于stack exchange,提问作者Vipin
相关产品推荐
相关产品推荐

