Pandas实现:基于分组处理修改列值并新增overbook列的需求
解决DataFrame分组标记与ID替换问题
针对你给出的DataFrame数据和需求,这里提供一个简洁的pandas实现方案,完全匹配你要的预期输出:
import pandas as pd # 构造示例数据(如果你已有排序后的df,可跳过这部分直接使用你的数据) data = [ ['s1', 1, 'A', 0.2], ['s1', 2, 'B', 0.9], ['s1', 2, 'B', 0.4], ['s1', 3, 'C', 0.7], ['s1', 4, 'D', 0.8], ['s1', 4, 'D', 0.3], ['s1', 5, 'E', 0.6], ['s1', 6, 'F', 0.5], ['s1', 7, 'G', 0.7], ['s2', 1, 'A1', 0.6], ['s2', 2, 'B1', 0.5], ['s2', 3, 'C1', 1.1], ['s2', 3, 'C1', 0.6], ['s2', 4, 'D1', 0.7], ['s2', 5, 'E1', 0.6], ['s2', 6, 'F1', 0.7], ['s2', 7, 'G1', 1.2], ['s2', 7, 'G1', 0.7] ] df = pd.DataFrame(data, columns=['Session', 'slot_num', 'ID', 'prob']) # 你已执行的排序操作 df = df.sort_values(['Session', 'slot_num'], ascending=True) # 步骤1:新增overbook列 # 给每个(Session, slot_num)分组内的行生成从0开始的序号 df['group_rank'] = df.groupby(['Session', 'slot_num']).cumcount() # 先默认第一行是'no',后续行是'booking' df['overbook'] = df['group_rank'].apply(lambda x: 'no' if x == 0 else 'booking') # 对分组内有多行的第一行,将overbook改为'yes' multi_row_mask = (df['group_rank'] == 0) & (df.groupby(['Session', 'slot_num'])['group_rank'].transform('max') > 0) df.loc[multi_row_mask, 'overbook'] = 'yes' # 步骤2:替换分组内第二行及以后的ID为'TBF' df.loc[df['group_rank'] > 0, 'ID'] = 'TBF' # 移除临时的group_rank列 df = df.drop(columns=['group_rank']) # 查看最终结果 print(df)
代码逻辑说明
- 分组行编号:通过
cumcount()给每个分组内的行生成序号,轻松区分分组内的第一行和后续行。 - overbook列设置:先做基础赋值,再通过掩码精准定位“分组内有多行的第一行”,将其overbook值改为'yes'。
- ID替换:直接通过序号筛选出分组内第二行及以后的行,批量替换ID为'TBF'。
最终输出结果
Session slot_num ID prob overbook 0 s1 1 A 0.2 no 1 s1 2 B 0.9 yes 2 s1 2 TBF 0.4 booking 3 s1 3 C 0.7 no 4 s1 4 D 0.8 yes 5 s1 4 TBF 0.3 booking 6 s1 5 E 0.6 no 7 s1 6 F 0.5 no 8 s1 7 G 0.7 no 9 s2 1 A1 0.6 no 10 s2 2 B1 0.5 no 11 s2 3 C1 1.1 yes 12 s2 3 TBF 0.6 booking 13 s2 4 D1 0.7 no 14 s2 5 E1 0.6 no 15 s2 6 F1 0.7 no 16 s2 7 G1 1.2 yes 17 s2 7 TBF 0.7 booking
内容的提问来源于stack exchange,提问作者Danish
相关产品推荐
相关产品推荐

