如何更高效地在DataFrame列中应用递归函数而非for循环?
高效填充DataFrame的NaN为斐波那契数列
问题描述
给定如下DataFrame:
import numpy as np import pandas as pd df = pd.DataFrame({'a':[1, 1, np.nan, np.nan, np.nan, np.nan, np.nan]})
初始数据:
a 0 1.0 1 1.0 2 NaN 3 NaN 4 NaN 5 NaN 6 NaN
目标是用斐波那契数列填充所有NaN,得到:
a 0 1.0 1 1.0 2 2.0 3 3.0 4 5.0 5 8.0 6 13.0
当前通过显式for循环实现,但希望找到更高效的、无需遍历表格的方法。
解决方案
1. 线性递推滤波器(完全向量化,最优效率)
斐波那契数列满足线性递推关系 x[n] = x[n-1] + x[n-2],可以用scipy.signal.lfilter直接计算,全程无显式循环,适合大规模数据集:
from scipy.signal import lfilter n = len(df) # 递推公式的系数:对应x[n] - x[n-1] - x[n-2] = 0 b = [1] a = [1, -1, -1] # 构造初始输入:前两项为已知值,后续补0(会被滤波器覆盖) initial_vals = df['a'].dropna().values input_arr = np.concatenate([initial_vals, np.zeros(n - len(initial_vals))]) # 计算完整序列 fib_sequence = lfilter(b, a, input_arr) # 赋值回DataFrame df['a'] = fib_sequence
2. Numpy数组优化循环(无额外依赖,高效)
如果不想引入SciPy,将Pandas Series转为Numpy数组后再循环,避免loc的索引开销,速度远高于原生Pandas循环:
arr = df['a'].values for i in range(2, len(arr)): arr[i] = arr[i-1] + arr[i-2] df['a'] = arr
Numpy数组的内存连续,直接访问元素的开销远低于Pandas的loc方法,数据量越大优势越明显。
3. Pandas Expanding窗口(可读性优先)
用expanding窗口封装递推逻辑,代码更直观,但效率不如前两种(本质仍为逐行处理):
def compute_fib(s): if len(s) <= 2: return s.iloc[-1] return s.iloc[-1] + s.iloc[-2] df['a'] = df['a'].expanding().apply(compute_fib, raw=False)
内容的提问来源于stack exchange,提问作者Tamás Pápai
相关产品推荐
相关产品推荐

