如何按ID分组循环计算Impact与Prob乘积直至目标值并生成Res_Problem列
按ID分组实现循环计算生成Res_Problem列
初始数据(无Res_Problem列)
| ID | Problem | X | Impact | Prob |
|---|---|---|---|---|
| ID1 | 12 | IDC1 | 1 | 2 |
| ID1 | 12 | IDC2 | 2 | 2 |
| ID1 | 12 | IDC3 | 1 | 0 |
| ID1 | 12 | IDC4 | 1 | 0 |
| ID2 | 10 | IDB1 | 1 | 2 |
| ID2 | 10 | IDB1 | 1 | 2 |
核心思路
- 按
ID分组,每组独立计算,切换ID时重置初始剩余值 - 用变量跟踪当前剩余值(初始为该组
Problem的初始值),逐行扣除Impact*Prob的乘积 - 剩余值达到目标值(如示例中的6)后,后续行标记
NO LOOP;乘积为0的行直接标记NO LOOP - 新ID组的第一个有效计算行添加
New Loop前缀,匹配示例格式
代码实现
import pandas as pd # 构造初始DataFrame data = { 'ID': ['ID1', 'ID1', 'ID1', 'ID1', 'ID2', 'ID2'], 'Problem': [12, 12, 12, 12, 10, 10], 'X': ['IDC1', 'IDC2', 'IDC3', 'IDC4', 'IDB1', 'IDB1'], 'Impact': [1, 2, 1, 1, 1, 1], 'Prob': [2, 2, 0, 0, 2, 2] } df = pd.DataFrame(data) TARGET = 6 # 设定目标停止值 def process_single_group(group): current_value = group['Problem'].iloc[0] target_reached = False res_problem = [] for idx, row in group.iterrows(): product = row['Impact'] * row['Prob'] # 已达目标或乘积为0,直接标记NO LOOP if target_reached or product == 0: res_problem.append('NO LOOP') continue # 计算新剩余值并生成文本 new_value = current_value - product if idx == group.index[0]: # 组内第一行,添加New Loop前缀 text = f'New Loop ({current_value}-{product})={new_value}' else: text = f'({current_value}-{product})={new_value}' # 检查是否达到目标 if new_value == TARGET: text += ' STOP' target_reached = True res_problem.append(text) current_value = new_value group['Res_Problem'] = res_problem return group # 分组处理并生成结果 result_df = df.groupby('ID', group_keys=False).apply(process_single_group) print(result_df)
运行结果
| ID | Problem | X | Impact | Prob | Res_Problem |
|---|---|---|---|---|---|
| ID1 | 12 | IDC1 | 1 | 2 | (12-2)=10 |
| ID1 | 12 | IDC2 | 2 | 2 | (10-4)=6 STOP |
| ID1 | 12 | IDC3 | 1 | 0 | NO LOOP |
| ID1 | 12 | IDC4 | 1 | 0 | NO LOOP |
| ID2 | 10 | IDB1 | 1 | 2 | New Loop (10-2)=8 |
| ID2 | 10 | IDB1 | 1 | 2 | (8-2)=6 STOP |
关键细节说明
groupby('ID', group_keys=False)确保分组处理后保留原DataFrame的结构,避免额外的分组索引current_value跟踪每组的实时剩余值,target_reached变量控制循环停止逻辑,避免无效计算- 针对组内第一行的特殊格式处理,完全匹配示例中的
New Loop标记规则
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

