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

如何用Python-Pandas基于UserID检测重叠项目报名?

问题描述

现有三个独立CSV文件:

  • Exit文件:包含退出日期、UserID、ProjectID
  • Entry文件:包含报名日期、UserID、ProjectID
  • Project文件:包含有效ProjectID及ProjectType(有效值为0、1、2)

需求:找出在有效项目中存在重叠报名的用户——即同一用户出现两次报名日期早于一次退出日期的情况。

原思路:先用isin()筛选有效项目ID的数据集,再为每个UserID创建包含日期和事件类型的数组,排序后检查是否符合“奇数项为报名、偶数项为退出”的规则,不符合则判定为存在重叠。但不想用iterrows()迭代,希望用向量操作实现。

原代码片段:

exit = pd.read_csv('exit.csv')
enroll = pd.read_csv('enroll.csv')
project = pd.read_csv('project.csv')

df = pd.DataFrame(project)
ProjectTypes = [0, 1, 2]
project_valid = df[(df['ProjectType'].isin(ProjectTypes))]

df = pd.DataFrame(enroll)
enrollvalid = (df['ProjectID'].isin(project_valid['ProjectID']))
print("Enroll valids \n")
df = df[enrollvalid]

# 输出有效用户ID
print(df['userID'])
解决方案

1. 数据预处理:过滤有效项目数据

首先统一筛选出有效项目对应的报名和退出记录:

import pandas as pd

# 读取数据
exit_df = pd.read_csv('exit.csv')
enroll_df = pd.read_csv('enroll.csv')
project_df = pd.read_csv('project.csv')

# 筛选有效项目(ProjectType为0、1、2)
valid_project_ids = project_df[project_df['ProjectType'].isin([0,1,2])]['ProjectID'].unique()

# 过滤报名和退出数据,只保留有效项目的记录
enroll_valid = enroll_df[enroll_df['ProjectID'].isin(valid_project_ids)].copy()
exit_valid = exit_df[exit_df['ProjectID'].isin(valid_project_ids)].copy()

2. 构造统一事件序列(替代iterrows的核心操作)

把报名和退出数据合并,标记事件类型,然后按用户和日期排序:

# 为报名数据添加事件类型标记(1代表报名)
enroll_valid['event_type'] = 1
enroll_valid = enroll_valid.rename(columns={'报名日期': 'date'})[['UserID', 'date', 'event_type']]

# 为退出数据添加事件类型标记(-1代表退出)
exit_valid['event_type'] = -1
exit_valid = exit_valid.rename(columns={'退出日期': 'date'})[['UserID', 'date', 'event_type']]

# 合并两个事件数据集
events = pd.concat([enroll_valid, exit_valid], ignore_index=True)

# 按UserID分组,对每个用户的事件按日期排序
events['date'] = pd.to_datetime(events['date'])  # 确保日期是datetime类型
events_sorted = events.sort_values(by=['UserID', 'date'])

3. 检测重叠报名(向量式操作,无需迭代)

通过计算累计事件值来检测重叠:累计值>1时,说明当前存在未退出的报名(重叠)。

# 按用户计算累计事件值
events_sorted['active_enrolls'] = events_sorted.groupby('UserID')['event_type'].cumsum()

# 找出存在重叠的用户:只要该用户有任意一条记录的active_enrolls>1,就判定为重叠
overlap_users = events_sorted[events_sorted['active_enrolls'] > 1]['UserID'].unique()

print("存在重叠报名的用户ID:", overlap_users)

更优检测逻辑说明

这种方法比“检查奇偶项”更准确:

  • 无需依赖“报名-退出严格交替”的假设,能处理多次报名/退出的复杂场景
  • 完全用Pandas的分组和向量运算实现,效率远高于iterrows()迭代
  • 直接通过累计值判断当前活跃报名数,逻辑清晰且覆盖所有重叠情况

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 17:33:23