为何Pandas rolling apply指定axis=1时抛出ValueError?
Pandas Rolling Apply(axis=1) 抛出ValueError的原因及解决办法
问题现象
对DataFrame调用rolling(window=..., axis=1).apply()时会抛出ValueError,错误表现为程序试图将输出拆解到DataFrame的列而非行中;但使用内置窗口方法(如.min())或先转置DataFrame再用axis=0执行apply则能正常运行。
错误原因
这是Pandas通用apply方法在处理行方向(axis=1)滚动窗口时的实现缺陷:
- 当
axis=1且使用默认raw=False时,Pandas会将行窗口数据以Series形式传递给自定义函数,且期望函数返回标量; - 但内部输出处理逻辑未正确适配行滚动场景,错误地尝试将标量结果拆解为与输入窗口同维度的结构,最终导致维度不匹配的ValueError。
而Pandas的内置窗口方法(如.min())是针对不同axis单独优化的原生实现,不走通用apply的处理流程,因此能正常处理行滚动。
解决方案
方案1:转置DataFrame间接实现行滚动
先将DataFrame转置,把行滚动转为列滚动(axis=0),执行apply后再转置回来:
df.T.rolling(window=3, min_periods=3).apply(my_min).T
该方法无需修改自定义函数,适配性强。
方案2:设置raw=True适配numpy数组输入
将apply的raw参数设为True,此时Pandas会将窗口数据以numpy数组形式传递给函数,内部处理逻辑能正确识别标量输出:
# 修改函数以支持numpy数组输入 def my_min(arr): return arr.min() # 执行行滚动apply df.rolling(window=3, min_periods=3, axis=1).apply(my_min, raw=True)
如果需要兼容Series和numpy数组输入,函数可写成:
def my_min(x): return np.min(x)
内容的提问来源于stack exchange,提问作者LarryBird
相关产品推荐
相关产品推荐

