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

如何提升DataFrame全列自定义函数apply操作的执行效率?

问题:优化DataFrame列级最近非零值逆位置计算效率

我实现了以下自定义函数,用于返回数值型pd.Series中最后一个非零值的逆位置:若最后一个值非零则返回1,若所有值均为非零则返回0:

def calculate_recency_for_one_column(column: pd.Series) -> int:
    """Returns the inverse position of the last non-zero value in a pd.Series of numerics.
    If the last value is non-zero, returns 1. If all values are non-zero, returns 0."""
    non_zero_values_of_col = column[column.astype(bool)]
    if non_zero_values_of_col.empty:
        return 0
    return len(column) - non_zero_values_of_col.index[-1]

我通过以下代码将该函数应用于示例DataFrame的所有列:

df = pd.DataFrame(np.random.binomial(n=1, p=0.001, size=[1000000]).reshape((1000,1000)))
df.apply(lambda column: calculate_recency_for_one_column(column),axis=0)

执行结果如下:

0      436
1        0
2      624
3        0
      ... 
996    155
997    715
998    442
999    163
Length: 1000, dtype: int64

功能运行正常,但由于该操作需要频繁执行,我需要更高效的替代方案。我认为calculate_recency_for_one_column()函数本身效率尚可,df.apply()存在最大优化空间。以下是原方法的基准测试结果(执行100次):

>>> timeit.timeit(lambda: df.apply(lambda column: calculate_recency_for_one_column(column),axis=0), number=100)
14.700050864834338

优化方案测试结果

更新
Mustafa提供的方案测试结果:

>>> timeit.timeit(lambda: pd.Series(np.where(df.eq(0).all(), 0, len(df) - df[::-1].idxmax())), number=100)
0.8847485752776265

padu提供的方案测试结果:

>>> timeit.timeit(lambda: df.apply(calculate_recency_for_one_column_numpy, raw=True, axis=0), number=100)
0.8892530500888824

内容的提问来源于stack exchange,提问作者Viktor

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:46:00