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

Pandas按同一ID对DataFrame执行多条件状态修改求助

解决方案

首先确保日期列是可比较的datetime类型,再通过分组提取基准日期,最后组合条件修改Status:

步骤1:准备数据并转换日期类型

import pandas as pd

# 构造示例数据
data = {
    'ID': [42872, 42872, 42872, 9999],
    'user': ['luaquint@a.com.co', 'andres@a.com.co', 'luaquint@a.com.co', 'luaquint@a.com.co'],
    'reception_date': ['2022-03-30', '2022-03-01', '2022-03-07', '2022-03-07'],
    'end_date': ['2022-03-30', '2022-03-04', '2022-03-30', '2022-03-30'],
    'Status': ['Accepted', 'Returned', 'In Study', 'Rejected']
}
df = pd.DataFrame(data)

# 转换end_date为datetime类型(字符串无法直接比较大小)
df['end_date'] = pd.to_datetime(df['end_date'])

步骤2:提取每个ID的Accepted记录基准日期

# 按ID分组,获取每个组中Status为Accepted的最大end_date(兼容多Accepted记录场景)
accepted_end = df[df['Status'] == 'Accepted'].groupby('ID')['end_date'].max().rename('accepted_end')

# 将基准日期合并到原表,每个ID的所有行都能拿到对应的判断值
df = df.merge(accepted_end, on='ID', how='left')

步骤3:组合条件修改Status

# 构建筛选条件:
# 1. 当前ID存在Accepted记录(accepted_end不为空)
# 2. 当前记录Status是"In Study"
# 3. Accepted记录的end_date >= 当前记录的end_date
condition = (df['accepted_end'].notna()) & (df['Status'] == 'In Study') & (df['accepted_end'] >= df['end_date'])

# 对符合条件的行修改Status
df.loc[condition, 'Status'] = 'Accepted'

# 移除辅助列
df = df.drop('accepted_end', axis=1)

最终输出

ID               user reception_date   end_date    Status
0  42872  luaquint@a.com.co     2022-03-30 2022-03-30  Accepted
1  42872    andres@a.com.co     2022-03-01 2022-03-04  Returned
2  42872  luaquint@a.com.co     2022-03-07 2022-03-30  Accepted
3   9999  luaquint@a.com.co     2022-03-07 2022-03-30  Rejected

关键说明

  • 必须转换日期类型:字符串格式的日期无法直接做大小比较,这是新手容易踩的坑。
  • 分组+merge比apply更高效:apply逐行处理在数据量大时速度慢,分组提取基准值再合并属于Pandas矢量化操作,性能更优。
  • 兼容多Accepted记录:如果一个ID有多个Accepted记录,取最大的end_date作为判断基准,保证逻辑严谨性。

内容的提问来源于stack exchange,提问作者Andrés HK

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.16 01:05:21