如何在Pandas中识别跨规则近1天的嵌套列表用户重复项
问题:计算跨规则近1天内重复出现的用户ID
原始数据集
rules user_list event_time row_number rule1 123,244,344 2024-09-20 1 rule1 125,346,421 2024-09-19 2 rule1 125,343,431 2024-09-18 3 rule2 125,344,423 2024-09-20 1 rule2 125,346,421 2024-09-19 2 rule3 125,348,331 2024-09-20 1 rule3 125,336,221 2024-09-19 2
可复现代码
import pandas as pd data = { 'rules': ['rule1', 'rule1', 'rule1', 'rule2', 'rule2', 'rule3', 'rule3'], 'user_list': ['123,244,344', '125,346,421', '125,343,431', '125,344,423', '125,346,421', '125,348,331', '125,336,221'], 'event_time': ['2024-09-20', '2024-09-19', '2024-09-18', '2024-09-20', '2024-09-19', '2024-09-20', '2024-09-19'], 'row_number': [1, 2, 3, 1, 2, 1, 2] } df = pd.DataFrame(data) df['event_time'] = pd.to_datetime(df['event_time'])
需求说明
新增dupe_users列,规则如下:
- 针对当前行
user_list中的每个用户ID,统计其在近1天内(其他行的event_time处于当前行event_time - 1天到当前行event_time之间)、**属于不同rule**的其他行中出现的次数,重复出现几次就将该用户ID列几次 - 匹配范围包含所有符合条件的行,包括
row_number=1的最新规则行
预期结果
rules user_list event_time row_number dupe_users rule1 123,244,344 2024-09-20 1 344 rule1 125,346,421 2024-09-19 2 125,125,346,421 rule1 125,343,431 2024-09-18 3 125 rule2 125,344,423 2024-09-20 1 125,344 rule2 125,346,421 2024-09-19 2 125,125,346,421 rule3 125,348,331 2024-09-20 1 125,125 rule3 125,336,221 2024-09-19 2 125,125
解决方案
步骤1:拆分用户列表并展开数据
先将每行的user_list拆分为单个用户ID,保留原始行索引用于后续合并:
# 拆分用户列表并展开为单行单用户的格式 expanded_df = df.assign(user=df['user_list'].str.split(',')).explode('user') # 保留原始行的索引标识 expanded_df = expanded_df.reset_index().rename(columns={'index': 'original_row'})
步骤2:匹配跨规则近1天的重复用户
遍历每个原始行,筛选符合条件的重复用户:
# 存储每个原始行对应的重复用户列表 row_dupes = {} for original_row in expanded_df['original_row'].unique(): # 获取当前行的规则、时间和所有用户 current_rule = df.loc[original_row, 'rules'] current_time = df.loc[original_row, 'event_time'] current_users = expanded_df[expanded_df['original_row'] == original_row]['user'].tolist() # 筛选条件:不同规则、时间在近1天内、非当前行、用户匹配 mask = (expanded_df['rules'] != current_rule) & \ (expanded_df['event_time'] >= current_time - pd.Timedelta(days=1)) & \ (expanded_df['event_time'] <= current_time) & \ (expanded_df['original_row'] != original_row) & \ (expanded_df['user'].isin(current_users)) # 收集所有匹配到的用户,按出现顺序拼接 matched_users = expanded_df.loc[mask, 'user'].tolist() row_dupes[original_row] = ','.join(matched_users) if matched_users else ''
步骤3:合并回原表生成最终结果
将匹配结果映射到原始DataFrame:
# 添加dupe_users列到原表 df['dupe_users'] = df.index.map(row_dupes) # 打印结果 print(df)
运行后即可得到与预期一致的输出。
内容的提问来源于stack exchange,提问作者max
相关产品推荐
相关产品推荐

