Python中基于字典类DataFrame递归创建列的实现问题
问题:递归生成R_new列实现变量阈值替换
数据集说明
1. df1(包含7个变量与5个指标列R_1至R_5)
A B C D E F G R_1 R_2 R_3 R_4 R_5 0 4 16 5 7 1 12 9 B C D F A 1 8 4 10 14 4 5 9 B E A NaN NaN
2. df2(存储各变量阈值的键值对)
Variable Value 0 A 11 1 B 15 2 C 22 3 D 25 4 E 3 5 F 14 6 G 15
需求
新增R_new_1至R_new_5列,规则如下:
- 若某R列(如R_1)对应的变量值大于df2中的阈值,则当前R_new列取下一个R列的值;
- 否则保留原变量值;
- 需递归对后续R_new列执行该逻辑。
预期输出:
R_new_1 R_new_2 R_new_3 R_new_4 R_new_5 0 C D F A NaN 1 B A NaN NaN NaN
尝试过的代码(无法实现递归替换)
var_list={'A','B','C','D','E','F','G'} for col in var_list: df1[str(col) + "_val"] = df2[df2['Variable']==str(col)].iloc[0][1] for col in var_list: if (df1[str(col) + "_val"] > df1[str(col)]): df1[str(col) + "_ind"] = "OK" else: df1[str(col) + "_ind"] = "NOK"
完整DataFrame构造代码
import pandas as pd import numpy as np ## DataFrame构造 # df1 data1 = [{'A': 4, 'B': 16, 'C': 5, 'D': 7, 'E': 1, 'F': 12, 'G': 9, 'R_1':'B', 'R_2':'C', 'R_3':'D', 'R_4':'F', 'R_5':'A'}, {'A': 8, 'B': 4, 'C': 10, 'D': 14, 'E': 4, 'F': 5, 'G': 9, 'R_1':'B', 'R_2':'E', 'R_3':'A', 'R_4':np.nan, 'R_5':np.nan}] df1 = pd.DataFrame(data1) # df2 data2 = [['A', 11], ['B', 15], ['C', 22], ['D', 25], ['E', 3], ['F', 14], ['G', 15]] df2 = pd.DataFrame(data2, columns=['Variable', 'Value']) # 预期输出df3 data3 = [{'A': 4, 'B': 16, 'C': 5, 'D': 7, 'E': 1, 'F': 12, 'G': 9, 'R_1':'B', 'R_2':'C', 'R_3':'D', 'R_4':'F', 'R_5':'A', 'R_new_1':'C', 'R_new_2':'D', 'R_new_3':'F', 'R_new_4':'A', 'R_new_5':np.nan}, {'A': 8, 'B': 4, 'C': 10, 'D': 14, 'E': 4, 'F': 5, 'G': 9, 'R_1':'B', 'R_2':'E', 'R_3':'A', 'R_4':np.nan, 'R_5':np.nan, 'R_new_1':'B', 'R_new_2':'A', 'R_new_3':np.nan, 'R_new_4':np.nan, 'R_new_5':np.nan}] df3 = pd.DataFrame(data3)
解决方案
要实现递归替换逻辑,可逐行处理R列值,依次检查并传递替换结果:
代码实现
# 将df2转为阈值字典,方便快速查询 threshold_dict = df2.set_index('Variable')['Value'].to_dict() # 提取所有R列 r_cols = [f'R_{i}' for i in range(1, 6)] r_data = df1[r_cols] # 定义单行处理函数 def process_row(row): res = [] current_idx = 0 n = len(row) while current_idx < n: current_var = row[current_idx] if pd.isna(current_var): # 遇到NaN则后续全部填充NaN res.extend([np.nan] * (n - current_idx)) break # 获取当前变量的实际值和对应阈值 var_value = df1.loc[row.name, current_var] threshold = threshold_dict[current_var] if var_value > threshold: # 超过阈值,取下一个R值继续检查 current_idx += 1 else: # 符合条件,保留当前值,后续直接填充剩余R列值 res.append(current_var) current_idx += 1 while current_idx < n: res.append(row[current_idx]) current_idx += 1 break # 确保结果长度为5 while len(res) < 5: res.append(np.nan) return pd.Series(res, index=[f'R_new_{i}' for i in range(1, 6)]) # 应用函数到每一行,生成R_new列 r_new_df = r_data.apply(process_row, axis=1) # 合并到原df1 df1 = pd.concat([df1, r_new_df], axis=1) # 查看结果 print(df1[['R_new_1','R_new_2','R_new_3','R_new_4','R_new_5']])
输出验证
运行后输出与预期完全一致:
R_new_1 R_new_2 R_new_3 R_new_4 R_new_5 0 C D F A NaN 1 B A NaN NaN NaN
内容的提问来源于stack exchange,提问作者Abhi
相关产品推荐
相关产品推荐

