pandas crosstab如何使用自定义列列表仅统计指定年份记录数
问题说明
待处理的源DataFrame结构如下:
ID,Region,year,output 1,ANZ,1978,1 1,ANZ,2019,1 1,ANZ,2021,1 1,ASEAN,2021,1 1,ASEAN,2021,2 1,ASEAN,2020,3 2,UK,2021,8 2,UK,2021,1 2,UK,2021,0
需实现的逻辑:
- 固定生成
year_2019、year_2020、year_2021、year_2022四个年份列 - 按
ID分组,统计每个ID下对应四个年份的记录数,填入对应列
原有实现用pd.crosstab会自动将数据中所有存在的年份都转为结果列,无法仅保留指定的4个年份,不符合需求。期望的输出结果如下:
ID,year_2019,year_2020,year_2021,year_2022 1,1,1,3,0 2,0,0,3,0
实现方案
以下两种方案均可支持400万行级别的数据处理:
方案1:基于原有crosstab逻辑补全列
在原有代码输出结果的基础上,筛选目标列、补全缺失年份即可:
import pandas as pd # 定义需要统计的目标年份 target_years = [2019, 2020, 2021, 2022] # 原有交叉统计逻辑 count_res = pd.crosstab( index=tf['ID'], columns=tf['year'], values=tf['year'], aggfunc='count' ).fillna(0) # 仅保留目标年份列,不存在的年份自动填充0 count_res = count_res.reindex(columns=target_years, fill_value=0) # 按要求重命名列 count_res.columns = [f'year_{y}' for y in target_years] # 将ID从索引还原为普通列 count_res = count_res.reset_index()
方案2:提前过滤数据(大数据量优先选)
针对百万级以上数据,先过滤掉非目标年份的记录,减少后续计算量,性能更优:
import pandas as pd target_years = [2019, 2020, 2021, 2022] # 先过滤出目标年份的记录,跳过无关年份的计算 filtered = tf[tf['year'].isin(target_years)] # 分组统计各ID各年份的记录数后转为宽表 count_res = filtered.groupby(['ID', 'year']).size().unstack(fill_value=0) # 补全所有目标年份列,无记录的年份填0 count_res = count_res.reindex(columns=target_years, fill_value=0) # 重命名列并还原ID为普通列 count_res.columns = [f'year_{y}' for y in target_years] count_res = count_res.reset_index()
两种方案输出结果完全匹配预期,其中方案2提前裁剪了无关数据,在400万行规模的数据集上运行效率更高。
内容的提问来源于stack exchange,提问作者The Great
相关产品推荐
相关产品推荐

