You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:45:36