Pandas数据列标记函数出现KeyError问题求助
问题:Pandas处理DataFrame列时出现KeyError
场景描述
从Excel读取Pandas DataFrame后,原本处理单列的代码运行正常:
tmd.iloc[:, 10] = tmd.iloc[:, 10].fillna(tmd.iloc[:, 10].mean()) tmd.iloc[tmd.iloc[:, 10] == 0, 10] = tmd.iloc[:, 10].mean() tmd.iloc[:, 10] = tmd.iloc[:, 10].where(~((tmd.iloc[:, 10] > 0) & (pd.Series.abs(tmd.iloc[:, 10].diff()) > 30)), tmd.iloc[:, 10].mean())
但为了处理多列编写checkFlags_current函数后,执行 tmd_flags['Load Current(A)'] = checkFlags_current(tmd.iloc[:, 10])时出现KeyError:
def checkFlags_current(var): """ This function calculates, Input(s): - var1: Current in Ampere Returns: - flags """ rows = len(var) flags = np.zeros((rows, 1)) for i in range(0, rows): if (var[i] > 0 & (abs(var[i+1] - var[i]) > 30)): flags[i] = 1 elif (pd.isnull(var[i])): flags[i] = 3 elif (var[i] == 0): flags[i] = 2 else: flags[i] = 0 flags = list(itertools.chain(*flags)) return flags
错误信息:
File "D:\AssetManager\Scripts\req_functions.py", line 1215, in checkFlags_current if (var[i] > 0 & (abs(var[i+1] - var[i]) > 30)): File "C:\Users\jadha\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\series.py", line 958, in __getitem__ return self._get_value(key) File "C:\Users\jadha\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\series.py", line 1069, in _get_value loc = self.index.get_loc(label) File "C:\Users\jadha\AppData\Local\Packages\PythonSoftwareFoundation.Python.3.9_qbz5n2kfra8p0\LocalCache\local-packages\Python39\site-packages\pandas\core\indexes\range.py", line 387, in get_loc raise KeyError(key) from err KeyError: 32073
错误原因
- 循环越界:当
i遍历到最后一行(索引为rows-1)时,i+1超出了Series的索引范围,导致无法找到对应标签。 - 运算符优先级错误:
var[i] > 0 & (...)中,位运算符&的优先级高于比较运算符>,会先计算0 & (...),导致逻辑判断错误。 - 索引访问方式错误:用
var[i]是按标签索引,而非位置索引,如果Series的索引不是连续整数(或默认RangeIndex),会出现KeyError,应该用iloc按位置访问。
修复方案
方案1:修复循环逻辑
import numpy as np import pandas as pd def checkFlags_current(var): rows = len(var) # 初始化一维数组,避免后续展平操作 flags = np.zeros(rows, dtype=int) # 先批量处理空值和0值,效率更高 flags[pd.isnull(var)] = 3 flags[var == 0] = 2 # 循环范围限制到rows-2,避免访问i+1越界 for i in range(rows - 1): # 修正运算符优先级,用括号包裹比较表达式,使用逻辑and if (var.iloc[i] > 0) and (abs(var.iloc[i+1] - var.iloc[i]) > 30): flags[i] = 1 return flags.tolist() # 调用方式不变 tmd_flags['Load Current(A)'] = checkFlags_current(tmd.iloc[:, 10])
方案2:使用Pandas向量化操作(推荐)
Pandas的向量化操作比循环效率更高,且避免索引问题:
import pandas as pd def checkFlags_current(var): # 初始化flags为0 flags = pd.Series(0, index=var.index) # 批量设置各条件对应的flag值 flags[var.isna()] = 3 flags[var == 0] = 2 # 计算差值条件:当前值>0,且下一个值与当前值的差的绝对值>30 diff_condition = (var > 0) & (var.diff().abs().shift(-1) > 30) flags[diff_condition] = 1 return flags.tolist() # 调用方式不变 tmd_flags['Load Current(A)'] = checkFlags_current(tmd.iloc[:, 10])
内容的提问来源于stack exchange,提问作者Shraddha Jadhav
相关产品推荐
相关产品推荐

