如何在Pandas DataFrame中实现按ID及年度重置的特定值累计计数
问题与解决方案
问题背景
已有按ID升序、Date降序排序的DataFrame df:
import pandas as pd data = [ [1, '2021-04-28', 1], [1, '2021-02-28', 2], [1, '2020-12-23', 11], [1, '2020-11-29', 1], [2, '2021-07-07', 1], [2, '2021-06-20', 4], [2, '2021-05-26', 8], [2, '2021-04-08', 1], [2, '2021-03-03', 3], [2, '2021-02-03', 1], [2, '2021-01-13', 9], [2, '2020-12-23', 12], [3, '2021-06-02', 1], [3, '2021-05-08', 1], [3, '2021-04-08', 9], [3, '2021-01-17', 1], [3, '2020-12-23', 4], [3, '2020-12-02', 1], [3, '2020-11-14', 2] ] df = pd.DataFrame(data, columns=['ID', 'Date', 'Place']) df['Date'] = pd.to_datetime(df['Date'])
需要添加两列:
- Number of 1:每个
ID下Place列值为1的累计计数(从最早日期到当前日期的总数) - Recent Number of 1:
Place列值为1的累计计数,每年重置(仅统计当前年份内从最早日期到当前日期的总数)
期望输出如下:
ID Date Place Number of 1 Recent Number of 1 0 1 2021-04-28 1 2 1 1 1 2021-02-28 2 1 0 2 1 2020-12-23 11 1 1 3 1 2020-11-29 1 1 1 4 2 2021-07-07 1 3 3 5 2 2021-06-20 4 2 2 6 2 2021-05-26 8 2 2 7 2 2021-04-08 1 2 2 8 2 2021-03-03 3 1 1 9 2 2021-02-03 1 1 1 10 2 2021-01-13 9 0 0 11 2 2020-12-23 12 0 0 12 3 2021-06-02 1 4 2 13 3 2021-05-08 1 3 1 14 3 2021-04-08 9 2 1 15 3 2021-01-17 1 2 1 16 3 2020-12-23 4 1 1 17 3 2020-12-02 1 1 1 18 3 2020-11-14 2 0 0
解决方案
步骤1:创建Place值为1的标记列
生成辅助列,标记Place是否等于1:
df['is_1'] = df['Place'].eq(1).astype(int)
步骤2:生成Number of 1列
原数据按Date降序排列,需先按ID和Date升序排序,对每个ID组的is_1做累计求和,再将结果映射回原索引顺序:
df['Number of 1'] = df.sort_values(['ID', 'Date']).groupby('ID')['is_1'].cumsum().reindex(df.index)
步骤3:生成Recent Number of 1列
提取年份后,按ID和年份分组,同样按日期升序累计后映射回原顺序:
df['year'] = df['Date'].dt.year df['Recent Number of 1'] = df.sort_values(['ID', 'Date']).groupby(['ID', 'year'])['is_1'].cumsum().reindex(df.index)
步骤4:清理临时列
删除不再需要的辅助列:
df.drop(['is_1', 'year'], axis=1, inplace=True)
内容的提问来源于stack exchange,提问作者Apook
相关产品推荐
相关产品推荐

