Python pandas按ID日期分组提取指定元素间数据生成Another Pass列
解决方案
原代码核心问题
- 未给每个ID+日期分组匹配对应的条件对,无法准确获取条件值对应的起止Rank
- 循环赋值逻辑错误,每次迭代都会覆盖整列数据,且
between默认是闭区间会包含起止点本身的Info值,不符合需求 - 分组键存在拼写错误(
'Date '多了尾部空格),导致分组匹配失效
修正后完整代码
import pandas as pd # 你已定义的条件列表 cond_list = [{'LQ','DA'},{'HJ','OP'}] # 第一步:保留原筛选逻辑,修正未定义cond的问题 cond_all = [val for cond in cond_list for val in cond] mask = df.groupby(['ID', 'Date'])['Info'].agg(set).apply(lambda x: any([c.issubset(x) for c in cond_list])) data_set = df.set_index(['ID', 'Date']).loc[mask].reset_index() # 第二步:定义分组处理函数,每个ID+日期组单独计算目标值 def get_pass_info(group): # 匹配当前组对应的条件对 info_set = set(group['Info']) match_cond = next(c for c in cond_list if c.issubset(info_set)) # 获取两个条件值对应的Rank,保证小值为起、大值为终 v1, v2 = tuple(match_cond) r1 = group.loc[group['Info'] == v1, 'Rank'].iloc[0] r2 = group.loc[group['Info'] == v2, 'Rank'].iloc[0] start_r, end_r = (r1, r2) if r1 < r2 else (r2, r1) # 提取两个Rank之间的Info(排除起止点本身) pass_vals = group.loc[(group['Rank'] > start_r) & (group['Rank'] < end_r), 'Info'].tolist() return pd.Series({'Another Pass': pass_vals}) # 第三步:分组计算后合并结果到原数据集 pass_res = data_set.groupby(['ID', 'Date'], group_keys=False).apply(get_pass_info).reset_index() dt_final = pd.merge(data_set, pass_res, on=['ID', 'Date'], how='left')
代码说明
- 核心通过
groupby.apply对每个ID+日期分组单独处理,不会出现跨组的Rank匹配错误 - 自动识别当前组对应的条件对,动态计算起止Rank,无需提前提取Rank数组
- 筛选逻辑用严格的大于/小于判断,排除起止点本身的Info值,完全匹配示例输出要求
- 计算得到的
Another Pass列会自动匹配到对应分组的所有行,同组数据共享该列值
内容的提问来源于stack exchange,提问作者user17037971
相关产品推荐
相关产品推荐

