基于条件为DataFrame列打标签:Paid/UnPaid状态判定求助
解决方案
核心逻辑:对每个Id,先按时间顺序排序数据,取最近的3条记录(不足3条则取全部),若这部分记录的processed和success列全为0,标记为UnPaid,否则标记为Paid。
具体代码实现
import pandas as pd # 加载原始数据 data = { 'Id': ['A', 'A', 'A', 'B', 'B', 'B', 'B', 'C', 'C', 'C'], 'Month': ['Jan', 'Feb', 'Mar', 'Jan', 'Feb', 'Mar', 'Apr', 'Dec', 'Jan', 'Feb'], 'Year': [2021, 2021, 2021, 2021, 2021, 2021, 2021, 2021, 2022, 2022], 'processed': [0, 0, 1, 0, 0, 0, 0, 0, 0, 1], 'success': [0, 1, 0, 1, 0, 0, 0, 0, 0, 0] } df = pd.DataFrame(data) # 生成可排序的日期列,确保时间顺序正确 df['date'] = pd.to_datetime(df['Month'] + ' ' + df['Year'].astype(str)) # 按Id分组处理每个用户的状态 result = df.groupby('Id').apply(lambda group: { 'final_status': 'UnPaid' if (group[['processed', 'success']].tail(3) == 0).all().all() else 'Paid' }).reset_index() # 调整为目标格式 result.columns = ['Id', 'final_status'] print(result)
代码关键点说明
- 日期转换:用
pd.to_datetime把Month和Year合并为标准日期,避免月份缩写导致的排序错误(比如确保C的Dec2021→Jan2022→Feb2022顺序正确)。 - 分组处理:通过
groupby('Id')对每个用户单独计算状态。 - 最后3条校验:
tail(3)取最近3条记录,(group[['processed', 'success']].tail(3) == 0).all().all()逐层校验:- 第一层
all():确保单条记录的processed和success都为0; - 第二层
all():确保所有取到的记录都满足全0条件。
- 第一层
运行结果
Id final_status 0 A Paid 1 B UnPaid 2 C Paid
内容的提问来源于stack exchange,提问作者Roshankumar
相关产品推荐
相关产品推荐

