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

如何在Pandas中基于DateTime按ID生成月度犯罪类型计数列

问题描述

现有一个存储犯罪事件的大型DataFrame df,包含四列,其中INCIDENT_DATE为datetime类型,犯罪类型分为Violent(暴力犯罪)、Property(财产犯罪)和非索引类。示例数据如下:

ID犯罪事件事件日期类型
XL123445严重袭击2018-12-29Violent
XL123445轻微袭击2018-12-29Violent
XL123445盗窃2018-12-30Property
TX56784盗窃2018-04-28Property
............
CA45678性袭击1991-10-23Violent
LA356890入室盗窃2018-12-21Property

需要生成一个新的DataFrame,按每个ID和月份统计暴力犯罪、财产犯罪的数量,以及该ID当月的事件总数,目标格式如下:

ID年月暴力犯罪财产犯罪总计
XL1234452018-081965450020154
TX567842011-07171532
...............
CA456781992-06100100200
LA3568901993-0505050

注:目标表格中LA356890行的“暴力犯罪”列原内容有误,已修正为0。

此前已通过以下代码生成按ID和Year_Month统计总事件数的DataFrame,但未区分犯罪类型:

df1 = (df.value_counts(['ID', df['INCIDENT_DATE'].dt.to_period('M').rename('Year_Month')])
     .rename('Count').reset_index())

请问如何沿用该逻辑生成所需的额外列?

解决方案

方法一:基于value_counts的链式写法(沿用原有逻辑)

在原有value_counts的基础上,加入犯罪类型作为统计维度,再通过透视表将类型转为列,最后计算总计:

result = (df
          # 提取年月列,统一命名为Year_Month
          .assign(Year_Month=df['INCIDENT_DATE'].dt.to_period('M'))
          # 按ID、年月、类型统计事件数,对应带维度的value_counts
          .value_counts(['ID', 'Year_Month', '类型'])
          .rename('Count')
          .reset_index()
          # 透视表将类型转为列,缺失值填充为0(代表当月无该类型犯罪)
          .pivot(index=['ID', 'Year_Month'], columns='类型', values='Count')
          .fillna(0)
          .astype(int)
          # 只保留需要的暴力和财产犯罪列,并重命名为中文
          .filter(['Violent', 'Property'])
          .rename(columns={'Violent': '暴力犯罪', 'Property': '财产犯罪'})
          # 计算当月事件总计
          .assign(总计=lambda x: x['暴力犯罪'] + x['财产犯罪'])
          # 重置索引,转为目标格式的平级列
          .reset_index())

方法二:groupby聚合(更高效的替代方案)

如果处理超大型数据集,groupby聚合的性能会更优,逻辑也更直接:

result = (df
          .assign(Year_Month=df['INCIDENT_DATE'].dt.to_period('M'))
          # 按ID和年月分组,对类型列做聚合统计
          .groupby(['ID', 'Year_Month'])['类型']
          .agg(
              暴力犯罪=lambda x: (x == 'Violent').sum(),
              财产犯罪=lambda x: (x == 'Property').sum()
          )
          # 计算总计
          .assign(总计=lambda x: x['暴力犯罪'] + x['财产犯罪'])
          .reset_index())

两种方法最终都会生成符合要求的DataFrame,其中方法一完全沿用了你最初使用value_counts的统计思路,方法二则更适合大规模数据的快速处理。


内容的提问来源于stack exchange,提问作者TheMaffGuy

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.29 00:37:05