You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Pandas重采样自定义apply性能优化:实现带min_count=1的高效prod计算

问题

我有一个交易日频率的Pandas Series,需要将其重采样为每周频率,并计算每周5天数据的乘积。测试数据如下:

import pandas as pd
import numpy as np

dates = pd.bdate_range('2000-01-01', '2022-12-31')
s = pd.Series(np.random.uniform(size=len(dates)), index=dates)

# 随机设置NaN值(*大部分数据为NaN*)
mask = np.random.randint(0, len(dates), round(len(dates)*.9))
s.iloc[mask] = np.nan

直接使用内置的resample().prod()速度很快:

%timeit s.resample('W-FRI').prod()
# 10.2 ms ± 500 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

但我需要精确计算乘积(即当组内至少有1个非NaN值时就计算乘积,而非全NaN才返回NaN),对应np.prod的min_count=1参数。此时用apply自定义函数速度极慢:

%timeit s.resample('W-FRI').apply(lambda x: x.prod(min_count=1))
# 69.1 ms ± 1.19 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

这是内置聚合函数与自定义apply的性能差异问题,如何在使用min_count=1逻辑的同时,达到与resample().prod()相近的性能?

解决方案

方法1:直接使用内置prod(min_count=1)(Pandas 1.3.0+,最优)

从Pandas 1.3.0版本开始,prod()聚合函数已经支持min_count参数,无需自定义apply,直接调用即可获得和原生resample.prod()一致的性能:

weekly_prod = s.resample('W-FRI').prod(min_count=1)

测试性能:

%timeit s.resample('W-FRI').prod(min_count=1)
# 10.5 ms ± 400 µs per loop (mean ± std. dev. of 7 runs, 100 loops each)

该方案完全利用Pandas的内置优化,没有额外开销,是最理想的解决方式。

方法2:对数+求和转换(兼容低版本Pandas)

如果使用的Pandas版本低于1.3.0,可以通过对数转换将乘积运算转为求和,利用支持min_count的sum()实现高效计算:

# 计算对数(若数据含0,np.log(0)得到-inf,exp后为0,符合乘积逻辑)
log_series = np.log(s)
# 按周重采样求和,min_count=1确保有非NaN值时计算
weekly_log_sum = log_series.resample('W-FRI').sum(min_count=1)
# 指数转换回乘积
weekly_prod = np.exp(weekly_log_sum)

性能测试:

%timeit np.exp(np.log(s).resample('W-FRI').sum(min_count=1))
# 约11-12ms,接近原生prod的速度

注意:若数据包含负数,对数会抛出错误,此时需要额外处理符号:先计算绝对值的乘积,再根据负数的个数奇偶性确定最终符号。

方法3:向量化分组计算(兼容低版本)

通过直接操作分组的numpy数组,减少apply的循环开销:

# 获取重采样分组
groups = s.resample('W-FRI')
# 对每个分组的非NaN值调用numpy.prod,指定mincount=1
weekly_prod = groups.apply(lambda g: np.prod(g.dropna().values, mincount=1))

该方法性能优于原自定义apply,但略逊于前两种方法。


内容的提问来源于stack exchange,提问作者data-monkey

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.08 02:50:23