如何为列表中每个DataFrame元素应用函数并按性别年份命名?
按性别&年份分组处理DataFrame并生成对应命名图像的解决方案
先梳理你原代码里的几个问题:
- 性别循环用了
range(0,3),但你的数据中sex只有0和1,会生成sex=2的空DataFrame,完全没必要 make_graph函数直接调用age和value,这俩是未指定来源的变量,应该用传入的DataFrame中的列- 仅存储筛选后的DataFrame,无法关联对应的性别和年份,后续没法实现按组合命名输出的需求
- 原代码中
year生成时用了high=2013,只能生成2008-2012的数据,拿不到2013年的样本
修正后的完整代码
import pandas as pd import numpy as np import matplotlib.pyplot as plt # 生成模拟数据,简化写法同时修正年份范围 df_toy = pd.DataFrame({ 'value': np.random.randint(low=1, high=1000, size=100000), 'age': np.random.choice(range(0, 92), 100000), 'sex': np.random.choice([0, 1], 100000), 'year': np.random.randint(low=2008, high=2014, size=100000) # high设为2014才能包含2013年 }) def format_data(df, sex, year): """按性别和年份筛选数据,返回新的DataFrame""" return df[(df["sex"] == sex) & (df["year"] == year)].copy() def make_graph(df_, sex, year): """生成散点图,并按性别+年份组合命名保存""" # 空数据判断,避免无数据时绘图报错 if df_.empty: print(f"注意:性别{sex}、年份{year}无数据,跳过绘图") return # 初始化画布,设置合适大小 plt.figure(figsize=(8, 6)) # 使用传入的DataFrame列绘图,避免全局变量问题 plt.scatter(df_['age'], df_['value'], alpha=0.5) # 添加标题和坐标轴标签,提升图像可读性 plt.title(f"年龄 vs 数值 - 性别{sex} | 年份{year}") plt.xlabel("年龄") plt.ylabel("数值") plt.grid(True) # 按要求命名保存图像,格式示例:sex_0_year_2008.png save_filename = f"sex_{sex}_year_{year}.png" plt.savefig(save_filename, dpi=300, bbox_inches='tight') plt.close() # 关闭画布释放内存,避免内存泄漏 # 第一步:将性别、年份与对应筛选后的DataFrame打包成元组存入列表,保留关联信息 grouped_data = [] for sex in [0, 1]: # 仅遍历数据中存在的性别值 for year in range(2008, 2014): # 覆盖2008-2013所有年份 filtered_df = format_data(df_toy, sex, year) grouped_data.append( (sex, year, filtered_df) ) # 第二步:遍历每个分组,生成对应命名的图像 for sex, year, df_ in grouped_data: make_graph(df_, sex, year) # 如果需要保存DataFrame文件,可添加此行 # df_.to_csv(f"sex_{sex}_year_{year}.csv", index=False)
核心改动说明
- 保留分组关联信息:不再单独存储DataFrame,而是把性别、年份和筛选结果打包成元组,后续处理时直接就能获取对应标识,完美解决命名问题
- 修正数据生成逻辑:将年份的
high参数改为2014,确保生成2008-2013的完整数据 - 完善绘图逻辑:
- 用传入的
df_的列绘图,避免全局变量引发的错误 - 增加空数据判断,防止无数据时绘图报错
- 按
sex_<性别>_year_<年份>格式保存图像,完全匹配需求
- 用传入的
- 优化循环范围:性别仅遍历0和1,避免生成无效的空DataFrame
内容的提问来源于stack exchange,提问作者Stata_user
相关产品推荐
相关产品推荐

