如何在Pandas DataFrame中创建依赖历史值的新列并修复循环错误
问题:Pandas按规则生成依赖新列的两列数据
需求说明
需要在DataFrame中新增Open_Value和Close_Value两列,规则如下:
- 当
Open_Flag[i] = 1时,Open_Value[i] = 1000,Close_Value[i] = Open_Value[i] * Change[i]; - 当
Open_Flag[i] = 0时,Open_Value[i] = Close_Value[i-1](取同组上一行的Close_Value),Close_Value[i] = Open_Value[i] * Change[i]。
原错误代码
import pandas as pd data = {'Date': ['2023-03-05', '2023-03-06', '2023-03-07', '2023-03-05', '2023-03-06', '2023-03-07'], 'Name': ['abc', 'abc', 'abc', 'xyz', 'xyz', 'xyz'], 'Change': [.9, .8, .96, .97, 1.3, 1.5], 'Open_Flag':[1,0,0,1,0,0]} data = pd.DataFrame(data) for i in range(len(df.Open_Flag)): if df.loc[i, 'Open_Flag'] == 1: df.loc[i, 'Open_Value'] = 1000 and df.loc[i, 'Close_Value'] = df[i,'Open_Value'] * df[i,'AlphaPicks Open Close Daily Return_R Script'] elif df.loc[i, 'pos'] == 1: df.loc[i+1, 'pos'] = df.loc[i, 'pos'] + df.loc[i, 'above_hi'] print(df)
报错信息
File "", line 3
df.loc[i, 'Open_Value'] = 1000 and df.loc[i, 'Close_Value'] = df[i,'Open_Value'] * df[i,'AlphaPicks Open Close Daily Return_R Script']
^
SyntaxError: cannot assign to operator
期望输出
Date Name Change Open_Flag Open_Value Close_Value 0 2023-03-05 abc 0.90 1 1000 900.0 1 2023-03-06 abc 0.80 0 900 720.0 2 2023-03-07 abc 0.96 0 720 691.2 3 2023-03-05 xyz 0.97 1 1000 970.0 4 2023-03-06 xyz 1.30 0 970 1261.0 5 2023-03-07 xyz 1.50 0 1261 1891.5
解决方案
问题分析
- 语法错误:用
and连接两个赋值语句,Python不允许这种写法,必须拆分; - 变量名不一致:将DataFrame赋值给
data,但循环中使用未定义的df; - 未分组处理:数据按
Name分组,每个组的计算独立,原代码会跨组取错误值; - 无关代码冗余:
pos相关逻辑与需求无关,需删除; - 列逻辑缺失:未补全
Open_Flag=0时Close_Value的计算逻辑。
修正代码(循环版)
import pandas as pd data = {'Date': ['2023-03-05', '2023-03-06', '2023-03-07', '2023-03-05', '2023-03-06', '2023-03-07'], 'Name': ['abc', 'abc', 'abc', 'xyz', 'xyz', 'xyz'], 'Change': [.9, .8, .96, .97, 1.3, 1.5], 'Open_Flag':[1,0,0,1,0,0]} # 统一变量名,初始化DataFrame df = pd.DataFrame(data) # 初始化新增列 df['Open_Value'] = 0.0 df['Close_Value'] = 0.0 # 按Name分组处理,保证每组独立计算 for name, group in df.groupby('Name'): idx_list = group.index for i in range(len(idx_list)): current_idx = idx_list[i] if df.loc[current_idx, 'Open_Flag'] == 1: df.loc[current_idx, 'Open_Value'] = 1000 df.loc[current_idx, 'Close_Value'] = df.loc[current_idx, 'Open_Value'] * df.loc[current_idx, 'Change'] else: # 取同组上一行的Close_Value df.loc[current_idx, 'Open_Value'] = df.loc[idx_list[i-1], 'Close_Value'] df.loc[current_idx, 'Close_Value'] = df.loc[current_idx, 'Open_Value'] * df.loc[current_idx, 'Change'] print(df)
修正代码(Pandas分组Apply版)
如果数据量较大,推荐用分组Apply的方式,更符合Pandas风格:
import pandas as pd data = {'Date': ['2023-03-05', '2023-03-06', '2023-03-07', '2023-03-05', '2023-03-06', '2023-03-07'], 'Name': ['abc', 'abc', 'abc', 'xyz', 'xyz', 'xyz'], 'Change': [.9, .8, .96, .97, 1.3, 1.5], 'Open_Flag':[1,0,0,1,0,0]} df = pd.DataFrame(data) def calculate_group_values(group): # 初始化组内新增列 group['Open_Value'] = 0.0 group['Close_Value'] = 0.0 for i in range(len(group)): if group.iloc[i]['Open_Flag'] == 1: group.iloc[i]['Open_Value'] = 1000 group.iloc[i]['Close_Value'] = group.iloc[i]['Open_Value'] * group.iloc[i]['Change'] else: group.iloc[i]['Open_Value'] = group.iloc[i-1]['Close_Value'] group.iloc[i]['Close_Value'] = group.iloc[i]['Open_Value'] * group.iloc[i]['Change'] return group # 分组应用计算函数,保持原索引 df = df.groupby('Name', group_keys=False).apply(calculate_group_values) print(df)
修正说明
- 拆分赋值语句,修复语法错误;
- 统一变量名,解决未定义问题;
- 按
Name分组处理,确保每组独立计算,避免跨组取值错误; - 补全
Close_Value的完整计算逻辑; - 删除无关的
pos代码,精简逻辑。
内容的提问来源于stack exchange,提问作者Zachary Marx
相关产品推荐
相关产品推荐

