如何基于动态日期筛选分组内的行?按参与者筛选首分钟数据
筛选每位参与者首分钟内的记录
需求说明
每位参与者有多条记录且起始时间不同,需要筛选出每位参与者首分钟内的所有行,起止日期需根据每个参与者的最早时间动态设置。
示例数据
| id | participant | start_time |
|---|---|---|
| 44414 | 1556 | 2023-04-18 09:35:41.100 |
| 36905 | 1435 | 2023-04-18 09:35:41.300 |
| 44416 | 1556 | 2023-04-18 09:35:42.100 |
| 44417 | 1556 | 2023-04-18 09:35:42.900 |
| 44418 | 1222 | 2023-04-18 09:35:43.100 |
| 44356 | 1899 | 2023-04-18 23:01:29.400 |
尝试的代码及错误
已将start_time转为 datetime 类型,尝试按参与者分组后用apply筛选,但出现错误:
df['start_time'] = pd.to_datetime(df['start_time']) x = df.sort_values('start_time',ascending=True).groupby(['participant']).apply(lambda g: pd.date_range(start=df['start_time'].min(), end = df['start_time'].max(), periods=len(g),freq='60S').to_series()).values
错误信息:
ValueError: Of the four parameters: start, end, periods, and freq, exactly three must be specified
错误分析
pd.date_range参数规则错误:该函数要求必须且只能指定start、end、periods、freq中的三个,同时指定四个会直接触发报错。- 逻辑偏差:代码使用全局的
df['start_time'].min()/max(),而非每个参与者分组内的最早时间,完全不符合“动态设置起止日期”的需求。
正确实现方案
方案1:添加辅助列筛选(直观易读)
先计算每个参与者的最早记录时间,再筛选出该时间后1分钟内的所有行:
# 转换时间列格式 df['start_time'] = pd.to_datetime(df['start_time']) # 给每条记录标记所属参与者的最早时间 df['first_record_time'] = df.groupby('participant')['start_time'].transform('min') # 筛选首分钟内的记录 filtered_df = df[df['start_time'] <= df['first_record_time'] + pd.Timedelta(minutes=1)] # 可选:移除辅助列 filtered_df = filtered_df.drop('first_record_time', axis=1)
方案2:分组内直接筛选(简洁高效)
利用groupby.apply在每个分组内完成筛选,无需额外辅助列:
df['start_time'] = pd.to_datetime(df['start_time']) filtered_df = df.sort_values('start_time').groupby('participant').apply( lambda group: group[group['start_time'] <= group['start_time'].min() + pd.Timedelta(minutes=1)] ).reset_index(drop=True)
预期结果
处理后的数据将保留每个参与者最早记录时间开始后1分钟内的所有行:
- participant 1556的3条记录均在首分钟内,全部保留
- participant 1435、1222、1899各仅1条记录,全部保留
内容的提问来源于stack exchange,提问作者London-35
相关产品推荐
相关产品推荐

