如何对category列A开头分组的time列从首行扣减固定值并保留原顺序
实现思路
- 先给原始DataFrame新增一列存储原始索引,保证最终结果可以恢复原始行顺序
- 按category列分组,对每个分组判断是否以A开头:
- 若为B开头分组,直接返回原分组数据
- 若为A开头分组,遍历分组内的行依次扣减固定额度,处理逻辑如下:
- 初始化剩余待扣减额度为固定值(示例为200)
- 逐行判断:剩余额度为0时直接保留当前行;当前行time值小于剩余额度时跳过该行,剩余额度扣减当前行time值;当前行time值大于等于剩余额度时,time扣减剩余额度后保留该行,剩余额度置为0
- 所有分组处理完成后,按原始索引列排序,删除临时新增的原始索引列即可得到结果
完整代码示例
import pandas as pd # 构造测试数据 data = { 'time': [150, 170, 100, 100, 70, 400, 100, 300, 100, 100, 100, 150, 200, 100], 'look': ['left', 'right', 'left', 'away', 'left', 'right', 'left', 'right', 'left', 'right', 'left', 'right', 'away', 'left'], 'category': ['B1', 'B1', 'B1', 'A1', 'A1', 'A1', 'A1', 'A2', 'A2', 'A2', 'B1', 'B1', 'B1', 'B1'] } df = pd.DataFrame(data) # 新增原始索引列用于后续恢复顺序 df['origin_idx'] = df.index # 定义固定扣减额度,可按需修改 DEDUCT_AMOUNT = 200 # 分组处理函数 def process_group(group): # 非A开头分组直接返回原数据 if not group['category'].iloc[0].startswith('A'): return group remaining_deduct = DEDUCT_AMOUNT result_rows = [] for _, row in group.iterrows(): if remaining_deduct <= 0: result_rows.append(row) continue # 当前行time不足以抵扣剩余额度,删除该行,额度顺延 if row['time'] < remaining_deduct: remaining_deduct -= row['time'] continue # 当前行time足够抵扣,扣减后保留该行,额度清零 new_row = row.copy() new_row['time'] -= remaining_deduct remaining_deduct = 0 result_rows.append(new_row) return pd.DataFrame(result_rows) # 分组处理后合并结果 processed_df = df.groupby('category', group_keys=False).apply(process_group) # 恢复原始行顺序,删除临时索引列 processed_df = processed_df.sort_values('origin_idx').drop('origin_idx', axis=1).reset_index(drop=True) print(processed_df)
内容的提问来源于stack exchange,提问作者anonymous
相关产品推荐
相关产品推荐

