基于多条件的数据集加减运算Python Pandas自动化实现问询
Pandas实现数据集匹配运算的通用方案
问题背景
现有两个数据集:
第一个数据集
| type | week | value |
|---|---|---|
| A | 1 | 10 |
| A | 2 | -1 |
| B | 1 | 50 |
| D | 4 | -5 |
第二个数据集
| type | group | week | value |
|---|---|---|---|
| A | 1 | 1 | 5 |
| A | 2 | 1 | 10 |
| D | 10 | 4 | 1 |
| D | 11 | 4 | 2 |
| D | 16 | 4 | 4 |
运算规则
需基于type和week字段匹配执行以下运算:
- 若第一个数据集的
value为正值:将该值加到第二个数据集对应type+week组中value最大的记录上 - 若第一个数据集的
value为负值:从第二个数据集对应type+week组的value最大值开始扣除,结果不得低于0;若最大值不足以扣除,则依次扣除次大值,直到扣完指定数值
目标结果
处理后得到的目标数据集如下:
| type | group | week | value |
|---|---|---|---|
| A | 1 | 1 | 5 |
| A | 2 | 1 | 20 |
| D | 10 | 4 | 1 |
| D | 11 | 4 | 1 |
| D | 16 | 4 | 0 |
实现方案
以下是基于Pandas的通用实现代码,适配大规模数据处理场景:
import pandas as pd # 加载数据集(实际场景替换为你的数据读取逻辑,如pd.read_csv) df1 = pd.DataFrame({ 'type': ['A', 'A', 'B', 'D'], 'week': [1, 2, 1, 4], 'value': [10, -1, 50, -5] }) df2 = pd.DataFrame({ 'type': ['A', 'A', 'D', 'D', 'D'], 'group': [1, 2, 10, 11, 16], 'week': [1, 1, 4, 4, 4], 'value': [5, 10, 1, 2, 4] }) # 保留原始索引,按type+week分组后对value降序排序 df2['original_idx'] = df2.index df2_sorted = df2.sort_values(['type', 'week', 'value'], ascending=[True, True, False]) # 合并两个数据集,无匹配的组赋值0 merged = df2_sorted.merge(df1, on=['type', 'week'], how='left', suffixes=('', '_df1')) merged['value_df1'] = merged['value_df1'].fillna(0) # 定义分组处理逻辑 def process_group(group): adjust_val = group['value_df1'].iloc[0] if adjust_val == 0: return group if adjust_val > 0: # 正值:加到组内最大的value记录 group.loc[group.index[0], 'value'] += adjust_val else: # 负值:从大到小依次扣除,确保不低于0 remaining = -adjust_val for idx in group.index: if remaining <= 0: break current_val = group.loc[idx, 'value'] deduct = min(current_val, remaining) group.loc[idx, 'value'] = max(current_val - deduct, 0) remaining -= deduct return group # 分组执行处理 processed = merged.groupby(['type', 'week'], group_keys=False).apply(process_group) # 恢复原始顺序并清理临时列 result = processed.sort_values('original_idx').drop(columns=['original_idx', 'value_df1']) # 输出结果 print(result.reset_index(drop=True))
代码说明
- 排序与索引保留:先对第二个数据集按
type+week+value降序排序,同时保留原始索引,确保处理后能恢复数据初始顺序 - 数据合并:将第一个数据集的匹配调整值合并到排序后的第二个数据集中,无匹配的组赋值0,避免干扰计算
- 分组处理:
- 正值直接追加到组内最大的
value记录 - 负值从大到小依次扣除,保证每个记录的
value最终不低于0
- 正值直接追加到组内最大的
- 结果恢复:按原始索引排序,得到符合预期的最终数据集
内容的提问来源于stack exchange,提问作者N_ote
相关产品推荐
相关产品推荐

