如何基于User ID统计Date列的变化次数并生成计数列?
解决方法:按User ID统计Date变更次数
你的需求核心是对每个User ID,统计其Date的不同取值的出现顺序——同一用户下Date变化时计数加1,同一Date的所有行计数保持一致。之前的代码之所以不符合要求,是因为你同时按Date和User ID分组统计了重复次数,这和需求刚好相反。
最简洁的实现方式:使用rank(method='dense')
Pandas的rank方法配合method='dense'可以完美实现这个需求——它会对每个分组内的Date值按出现顺序进行连续排名,同一Date的行将获得相同的排名。
步骤如下:
- 先确保Date列是日期类型(避免字符串排序出错)
- 按User ID分组,对Date列执行密集排名
代码示例:
import pandas as pd # 构造示例数据 data = { 'Date': ['01.05.20', '01.05.20', '02.05.20', '02.05.20', '02.05.20', '04.05.20', '05.05.20', '06.05.20', '09.05.20'], 'User ID': ['CT500', 'FC200', 'FC200', 'TH600', 'OR100', 'UI800', 'UI800', 'UI800', 'UI800'] } df = pd.DataFrame(data) # 转换Date列为日期类型 df['Date'] = pd.to_datetime(df['Date'], format='%d.%m.%y') # 生成No.of Changes列 df['No.of Changes'] = df.groupby('User ID')['Date'].rank(method='dense').astype(int) # 查看结果 print(df)
运行后会得到你期望的输出:
Date User ID No.of Changes 0 2020-05-01 CT500 1 1 2020-05-01 FC200 1 2 2020-05-02 FC200 2 3 2020-05-02 TH600 1 4 2020-05-02 OR100 1 5 2020-05-04 UI800 1 6 2020-05-05 UI800 2 7 2020-05-06 UI800 3 8 2020-05-09 UI800 4
另一种实现:手动检测Date变化并累积计数
如果你想更直观地理解逻辑,也可以通过检测每个用户内Date是否发生变化,再累积求和:
# 先按User ID和Date排序,确保顺序正确 df = df.sort_values(['User ID', 'Date']) # 标记当前行Date是否与同组前一行不同 df['is_new_date'] = df.groupby('User ID')['Date'].transform(lambda x: x != x.shift()) # 第一行没有前一行,所以标记为True df['is_new_date'] = df['is_new_date'].fillna(True) # 对每个用户的标记进行累积求和,得到变更次数 df['No.of Changes'] = df.groupby('User ID')['is_new_date'].cumsum().astype(int) # 可选:删除中间辅助列 df = df.drop('is_new_date', axis=1)
这种方法逻辑更清晰,适合需要自定义调整的场景,但rank方法更简洁高效。
内容的提问来源于stack exchange,提问作者Ak17
相关产品推荐
相关产品推荐

