求助:在同一图中绘制3组运动项目的可切换变量箱线图
问题排查与修正方案
原代码核心问题
- 功能不匹配需求:原函数仅支持绘制单个运动项目的箱线图,无法在同一图表中展示3个运动项目的数据。
- 冗余低效的循环:遍历所有30个学生ID再筛选对应运动,会对不属于该运动的ID执行无效查询,还会引入大量空值(NaN),导致箱线图数据异常。
- 数据处理逻辑可优化:手动循环计算每个ID的最大3值均值,远不如利用pandas分组聚合功能高效简洁。
- 内置类型命名冲突:使用
list作为变量名,覆盖了Python内置的list类型,可能引发后续隐性错误。
修正后的代码(适配多运动箱线图需求)
import pandas as pd import matplotlib.pyplot as plt def plot_multi_sport_boxplot(sports_list, variable): # 计算每个学生ID的指定变量最大3个值的均值 id_avg = df.groupby('ID')[variable].apply(lambda x: x.nlargest(3).mean()).reset_index() # 获取每个ID对应的唯一运动项目(每人仅参与一项) id_sport_map = df.groupby('ID')['sport'].first().reset_index() # 合并数据得到每个学生的运动与目标均值 merged_df = pd.merge(id_avg, id_sport_map, on='ID') # 整理每个运动对应的有效数据列表 sport_datasets = [] sport_labels = [] for sport in sports_list: # 过滤空值,仅保留当前运动的有效数据 valid_data = merged_df[merged_df['sport'] == sport][variable].dropna().tolist() sport_datasets.append(valid_data) sport_labels.append(f'{sport} - {variable}') # 绘制多箱线图 fig, ax = plt.subplots(figsize=(10, 6)) ax.boxplot(sport_datasets) ax.set_xticklabels(sport_labels) ax.set_ylabel(variable) ax.set_title(f'{variable} 各运动项目分布箱线图') plt.show() # 调用示例:传入3个运动项目列表和目标变量 plot_multi_sport_boxplot(['篮球', '足球', '游泳'], '肺活量')
关键修正说明
- 适配多运动需求:函数参数改为接收运动列表,一次性处理多个项目的数据,实现同一图表展示。
- 高效数据预处理:用
groupby批量计算每个ID的目标均值,避免循环遍历所有ID,大幅提升运行效率。 - 过滤无效数据:通过
dropna()移除空值,确保箱线图仅展示有效数据,避免异常图形。 - 优化代码规范性:避免使用内置类型作为变量名,同时优化图表标注,提升可读性。
内容的提问来源于stack exchange,提问作者Kkura
相关产品推荐
相关产品推荐

