Python循环使用loc报错求助:KeyError与TypeError问题排查
问题分析与修复方案
嘿,我来帮你搞定这个报错!你的代码核心问题是pandas的loc用法错误,还有一些不安全的赋值方式,导致了KeyError和TypeError。让我一步步给你拆解:
错误原因详解
loc的参数使用错误
你写的这行代码:data.loc[data['Dividend'].iloc[i+1] != 0, data['Adjusting Factor'].iloc[i+1]] = ...loc的正确语法是data.loc[行筛选条件/行索引, 列名],但你第二个参数传的是data['Adjusting Factor'].iloc[i+1]——这是取出了该行该列的具体数值,不是列名!pandas会把这个数值当成列名去查找,自然找不到(所以报KeyError),又因为你的DataFrame索引是日期类型,它还尝试把布尔值转成Timestamp,最后抛出TypeError。链式赋值的风险
你用data['Adjusted Premium'].iloc[i] = ...这种方式赋值,属于链式索引,可能触发SettingWithCopyWarning,而且在某些情况下会导致赋值不生效,这不是pandas推荐的安全赋值方式。
修复后的代码(循环版本)
如果你一定要用循环实现,我们修正loc的用法,改用更安全的索引方式:
for i in range(data.shape[0]): if i == (data.shape[0]-1): continue # 跳过最后一行,避免越界 # 检查下一行的Dividend是否不为0 if data['Dividend'].iloc[i+1] != 0: # 用iloc定位行和列:i+1行,Adjusting Factor列 adjust_col_idx = data.columns.get_loc('Adjusting Factor') data.iloc[i+1, adjust_col_idx] = (data['EQIX US EQUITY'].iloc[i] - data['Dividend'].iloc[i]) / data['EQIX US EQUITY'].iloc[i] # 安全赋值Adjusted Premium premium_col_idx = data.columns.get_loc('Adjusted Premium') data.iloc[i, premium_col_idx] = data['Put'].iloc[i] * data['Adjusting Factor'].iloc[i]
或者如果你习惯用loc(适合日期索引的场景):
for i in range(data.shape[0]): if i == (data.shape[0]-1): continue current_idx = data.index[i] next_idx = data.index[i+1] if data.loc[next_idx, 'Dividend'] != 0: data.loc[next_idx, 'Adjusting Factor'] = (data.loc[current_idx, 'EQIX US EQUITY'] - data.loc[current_idx, 'Dividend']) / data.loc[current_idx, 'EQIX US EQUITY'] data.loc[current_idx, 'Adjusted Premium'] = data.loc[current_idx, 'Put'] * data.loc[current_idx, 'Adjusting Factor']
更推荐的矢量化实现(避免循环)
pandas的优势是矢量化操作,效率比循环高得多,尤其是数据量大的时候。我们可以用shift()函数实现你的需求:
import numpy as np # 给下一行的Adjusting Factor赋值:当下一行Dividend不为0时,用当前行的计算值 data['Adjusting Factor'] = np.where( data['Dividend'].shift(-1) != 0, # 下一行Dividend不为0的条件 (data['EQIX US EQUITY'] - data['Dividend']) / data['EQIX US EQUITY'], # 计算值 data['Adjusting Factor'] # 条件不满足时保持原数值 ) # 计算Adjusted Premium data['Adjusted Premium'] = data['Put'] * data['Adjusting Factor']
这个写法既简洁又高效,完全不需要循环,也避免了索引错误的问题。
内容的提问来源于stack exchange,提问作者Tsz Chun Leung
相关产品推荐
相关产品推荐

