如何高效创建跨年级的学区年度平均成绩变量并移除年级列
如何高效创建跨年级的学区年度平均成绩变量并移除年级列
嗨,Kyle!我完全懂你面对30万条数据时逐行处理的崩溃感——别担心,用pandas的分组聚合功能就能轻松搞定这个需求,而且是完全向量化的高效操作,比手动循环快N倍。
核心思路
我们需要以**学区唯一ID(leaid)和年份(year)**为分组依据,把同一个学区同一年里所有年级的数学、英语成绩分别取平均值,这样聚合后的结果自然就没有grade变量了,每一行正好对应一个学区某一年的跨年级平均成绩。
具体代码实现
假设你已经导入了pandas,直接运行这段代码就行:
import pandas as pd # 按学区和年份分组,聚合计算数学、英语的跨年级平均分 df_aggregated = df_stat.groupby(['leaid', 'year']).agg( avg_math=('mean_link_math', 'mean'), # 把原数学成绩列的均值命名为avg_math avg_ela=('mean_link_ela', 'mean') # 把原英语成绩列的均值命名为avg_ela ).reset_index()
代码解释
groupby(['leaid', 'year']):告诉pandas要把数据按“学区+年份”的组合分组,每个组里就是同一个学区同一年的所有年级数据。agg(...):指定聚合规则,这里我们对mean_link_math和mean_link_ela分别计算均值,同时给新生成的列起好名字(avg_math和avg_ela)。reset_index():把分组用的leaid和year从索引变回普通列,这样结果的结构更符合你的需求——每行是一个独立的学区年度记录。
额外小贴士
- 如果你的数据里有缺失值,可以先过滤掉无效行再聚合:
# 先删除成绩列有缺失的行 df_clean = df_stat.dropna(subset=['mean_link_math', 'mean_link_ela']) # 再进行聚合 df_aggregated = df_clean.groupby(['leaid', 'year']).agg( avg_math=('mean_link_math', 'mean'), avg_ela=('mean_link_ela', 'mean') ).reset_index() - 你可以随机抽几个学区+年份的组合,对比原数据的年级成绩和聚合后的平均值,验证结果是否正确,比如:
# 随机选一个leaid和year sample_leaid = df_stat['leaid'].sample(1).iloc[0] sample_year = df_stat['year'].sample(1).iloc[0] # 查看原数据 print(df_stat[(df_stat['leaid'] == sample_leaid) & (df_stat['year'] == sample_year)]) # 查看聚合后的数据 print(df_aggregated[(df_aggregated['leaid'] == sample_leaid) & (df_aggregated['year'] == sample_year)])
备注:内容来源于stack exchange,提问作者Kyle Heideman
相关产品推荐
相关产品推荐

