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

Polars中行迭代:不规则采样时间序列的指数加权和快速计算

Polars中原生实现依赖前序结果的指数累加计算

你需要实现的是依赖前一行计算结果的指数累加逻辑(exp_sum[i] = exp_sum[i-1] * decay[i] + signal[i]),这类带状态的迭代计算无法向量化,想知道Polars是否有原生高性能实现,以及背后的原因。

目前没有Polars原生的高性能实现方式

核心原因:列存储的天然限制

Polars底层采用列存储架构,官方文档明确提到:

由于底层数据采用列存储,行迭代并非最优方式;如有可能,优先使用专用导出/输出方法。

列存储的优势是对整列做批量运算,而这类需要逐行依赖前序状态的计算,需要频繁跨行访问数据,完全违背了列存储的优化方向,因此Polars没有针对这类场景设计原生的高性能API。

当前最优方案:Polars + Numba

你现在用Polars转Numpy数组再调用Numba函数的方案,就是当前的最优解。如果想减少格式转换的开销,可以直接用Polars的to_numpy()提取列数据,计算后再转回Polars列,示例代码如下:

import polars as pl
import numba as nb
import numpy as np

@nb.jit(nopython=True)
def exponential_sum(signal, decay, initial_value=0):
    n = len(signal)
    exp_sum = np.zeros(n)
    exp_sum[0] = signal[0] if initial_value == 0 else initial_value * decay[0] + signal[0]
    for i in range(1, n):
        exp_sum[i] = exp_sum[i-1] * decay[i] + signal[i]
    return exp_sum

# 构造示例Polars DataFrame
df = pl.DataFrame({
    "times": [1.0, 2.0, 3.0, 4.0],
    "signal": [10, 20, 30, 40]
})

alpha = -0.5
# 计算decay列,填充第一行的null值
df = df.with_columns(
    decay=pl.col("times").diff().exp() * alpha
).fill_null(1.0)

# 提取数组并计算
signal_np = df["signal"].to_numpy()
decay_np = df["decay"].to_numpy()
exp_sum_np = exponential_sum(signal_np, decay_np)

# 将结果转回Polars列
df = df.with_columns(exp_sum=pl.Series(exp_sum_np))
print(df)

关于未来是否会支持原生实现

Polars的核心定位是向量化列处理引擎,这类带状态的逐行迭代计算不属于它的核心优化场景。除非社区有大量迫切需求,否则官方大概率不会推出原生API——毕竟这类场景Numba已经能高效解决,Polars没必要在自己的短板方向投入资源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 01:11:31