Python中apply函数报‘对象不可迭代’错误,如何处理行时引用前后行值?
解决Pandas中使用apply引用前后行数据报错的问题
原代码的核心问题是在apply的行处理函数内部反复调用df.shift(),这会导致每次处理一行都要对整个DataFrame执行移位操作,既浪费性能,也容易因为数据上下文的问题触发错误。另外,第一行的前一行、最后一行的后一行都是NaN值,直接计算也会得到NaN,需要的话可以额外处理。
以下是两种可行的解决方案:
方案一:用矢量化操作替代apply(推荐)
Pandas的矢量化操作比逐行apply高效得多,提前生成前一行和后一行的列,直接进行列级计算:
import pandas as pd data = { 'A': [1, 1, 1, 1, 1], 'B': [6, 7, 8, 9, 10] } df = pd.DataFrame(data) # 提前生成前一行、后一行的列 df['prev_A'] = df['A'].shift(1) df['prev_B'] = df['B'].shift(1) df['next_A'] = df['A'].shift(-1) df['next_B'] = df['B'].shift(-1) # 直接计算结果列 df['x'] = ((df['prev_B'] - df['prev_A']) - (df['next_B'] - df['next_A'])) # 按需保留或删除临时列 df = df[['A', 'B', 'x']] print(df)
输出结果:
A B x 0 1 6 NaN 1 1 7 -1.0 2 1 8 -1.0 3 1 9 -1.0 4 1 10 NaN
方案二:改进apply的用法(若必须用apply)
如果一定要用apply,不要在函数内部调用df.shift(),而是提前把移位后的列加入DataFrame,在处理函数中直接访问当前行的这些列:
import pandas as pd data = { 'A': [1, 1, 1, 1, 1], 'B': [6, 7, 8, 9, 10] } df = pd.DataFrame(data) # 提前添加前后行的列 df['prev_A'] = df['A'].shift(1) df['prev_B'] = df['B'].shift(1) df['next_A'] = df['A'].shift(-1) df['next_B'] = df['B'].shift(-1) def process_row(row): prev_value_A = row['prev_A'] prev_value_B = row['prev_B'] next_value_A = row['next_A'] next_value_B = row['next_B'] return ((prev_value_B - prev_value_A) - (next_value_B - next_value_A)) # 应用函数到每行,生成新列 df['x'] = df.apply(process_row, axis=1) df = df[['A', 'B', 'x']] print(df)
补充说明
- 第一行和最后一行的结果是NaN,因为第一行没有前一行,最后一行没有后一行,如果需要填充这些值,可以用
df['x'].fillna(0, inplace=True)之类的操作处理。 - 矢量化操作是Pandas的最佳实践,处理大数据集时性能比apply高几个数量级,优先选用方案一。
内容的提问来源于stack exchange,提问作者eashwar natarajan
相关产品推荐
相关产品推荐

