Pandas groupby分组内比较行并按条件处理used_bill_type列问题问询
解决方法
1. 预处理日期字段
首先将字符串格式的日期转换为Pandas datetime类型,避免直接比较字符串出现逻辑错误。
2. 分组逐行过滤
按TPID和SUBID字段分组,组内按start_date升序排序保证处理顺序,维护历史账单类型和对应过期时间的映射关系,逐行过滤掉used_bill_type中已过期的历史类型。
完整实现代码如下:
import pandas as pd # 构造原始数据集 data = pd.DataFrame({ 'TPID' : [757911,757911,757911,757911,757911,77909646,77909646,77909646], 'SUBID': ['40F8E','40F8E','D9F83','D9F83','D9F83','6DFB5','6DFB5','6DFB5'], 'start_date': ['7/1/2015','3/1/2021','7/1/2015','4/1/2017','10/1/2019','12/1/2017','8/1/2018','9/1/2020'], 'end_Date': ['2/1/2021','8/1/2021','8/1/2021','7/1/2021','8/1/2021','4/1/2018','9/1/2020','8/1/2021'], 'used_bill_type': [[],["Direct"],[],["EA"],["EA","Suites"],[],["EA"],["EA","Direct"]] }) # 转换日期格式 data['start_date'] = pd.to_datetime(data['start_date']) data['end_Date'] = pd.to_datetime(data['end_Date']) # 分组处理函数 def filter_expired(group): group = group.sort_values('start_date', ignore_index=True) # 存储历史账单类型对应的截止日期 type_end = {} for idx, row in group.iterrows(): # 过滤当前行的used_bill_type,仅保留未过期的类型 filtered = [t for t in row['used_bill_type'] if type_end.get(t, pd.Timestamp.min) >= row['start_date']] group.at[idx, 'used_bill_type'] = filtered # 将当前行对应的账单类型更新到历史映射中 if idx < len(group)-1: current_type = list(set(group.loc[idx+1, 'used_bill_type']) - set(row['used_bill_type']))[0] type_end[current_type] = row['end_Date'] return group # 执行分组处理得到结果 result = data.groupby(['TPID', 'SUBID'], group_keys=False).apply(filter_expired)
处理后结果
最终used_bill_type列的输出如下:
| 原行索引 | used_bill_type |
|---|---|
| 0 | [] |
| 1 | [] |
| 2 | [] |
| 3 | ['EA'] |
| 4 | ['EA', 'Suites'] |
| 5 | [] |
| 6 | [] |
| 7 | ['Direct'] |
内容的提问来源于stack exchange,提问作者Pradeep Kumar Jain LatentView
相关产品推荐
相关产品推荐

