使用Pandas按多列与时间规则分配唯一ID
解决方案:按规则为Pandas DataFrame分配唯一ID
核心思路
要满足你的三个规则,需分三步处理:
- 先按
name和timestamp完成排序,确保数据时序逻辑正确 - 生成连续分组键:识别连续的
date+name+product组合,解决切换产品再返回需新ID的问题 - 在每个连续分组内,基于
elapsed_time>100的断点拆分分组,最终生成唯一ID
完整代码实现
import pandas as pd # 模拟包含Carl场景的示例数据 data = { 'date': ['2024-01-01', '2024-01-01', '2024-01-01', '2024-01-01', '2024-01-01', '2024-01-02'], 'name': ['Carl', 'Carl', 'Carl', 'Carl', 'Carl', 'Alice'], 'product': ['A', 'B', 'A', 'A', 'A', 'X'], 'timestamp': ['2024-01-01 09:00', '2024-01-01 09:10', '2024-01-01 09:15', '2024-01-01 09:20', '2024-01-01 09:25', '2024-01-02 10:00'], 'elapsed_time': [50, 80, 120, 60, 70, 90] } df = pd.DataFrame(data) df['timestamp'] = pd.to_datetime(df['timestamp']) # 步骤1:按name和timestamp排序,保证时序正确 df = df.sort_values(['name', 'timestamp']).reset_index(drop=True) # 步骤2:生成连续组合的基础分组键——识别date/name/product的连续变化 df['base_group'] = (df[['date', 'name', 'product']] != df[['date', 'name', 'product']].shift()).any(axis=1).cumsum() # 步骤3:在每个基础分组内,对elapsed_time>100的断点进行累积计数 df['break_cum'] = df.groupby('base_group')['elapsed_time'].apply(lambda x: (x > 100).cumsum()) # 步骤4:合并分组键生成唯一ID df['unique_id'] = pd.factorize(df['base_group'].astype(str) + '_' + df['break_cum'].astype(str))[0] + 1 # 查看结果 print(df[['date','name','product','elapsed_time','unique_id']])
代码解释
- 排序:确保数据按用户和时间顺序排列,这是后续时序规则生效的基础
- base_group生成:对比当前行与上一行的
date/name/product组合,只要任一字段变化就生成新分组号。解决了Carl同一日期切换产品再返回原产品的问题——两次使用ProductA属于不连续组合,会被分配不同base_group - break_cum累积:在每个
base_group内部,对elapsed_time>100的行进行累积计数。一旦某行满足条件,后续同组所有行的break_cum值递增,进而生成新的最终分组 - unique_id生成:通过
factorize将合并后的分组键转化为唯一整数ID,完全匹配所有规则要求
运行结果
date name product elapsed_time unique_id 0 2024-01-01 Carl A 50 1 1 2024-01-01 Carl B 80 2 2 2024-01-01 Carl A 120 3 3 2024-01-01 Carl A 60 4 4 2024-01-01 Carl A 70 4 5 2024-01-02 Alice X 90 5
可见:
- Carl两次使用ProductA被分配不同ID(1和3)
- 行2的
elapsed_time>100,后续行3、4的ID递增为4,直到组合变更 - 所有不同
date/name/product组合或触发断点的行,都获得了符合规则的唯一ID
内容的提问来源于stack exchange,提问作者user22977701
相关产品推荐
相关产品推荐

