使用Polars优化Pandas均值编码性能遇阻,实现方式是否正确?
Polars均值编码性能优化分析
测试场景与结果
数据概况
<class 'pandas.core.frame.DataFrame'> RangeIndex: 10069612 entries, 0 to 10069611 Data columns (total 26 columns): dtypes: float64(1), int16(2), int8(15), object(8) memory usage: 873.9+ MB
测试代码及性能
- Pandas均值编码实现:
%timeit df["product_avg_sales"] = df.groupby("product")["sales"].transform("mean")
性能:219 ms ± 7.95 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
- 当前Polars实现:
df_polar = pl.from_pandas(df) %timeit df_polar.with_columns(pl.col('sales').mean().over(['product']).alias('product_avg_sales'))
性能:1.19 s ± 24.8 ms per loop (mean ± std. dev. of 7 runs, 1 loop each)
问题分析与优化方案
你的Polars写法语法正确,但性能落后可能由以下原因导致,对应优化方向如下:
- 窗口函数vs分组Join
Polars的窗口函数mean().over()在大基数分组场景下,性能不如先计算分组均值再关联回原表的方式。可以换用以下写法:
# 先计算分组均值 product_means = df_polar.group_by('product').agg(pl.col('sales').mean().alias('product_avg_sales')) # 关联回原表 df_polar = df_polar.join(product_means, on='product', how='left')
这种方式避免了窗口函数的逐行计算开销,在大表场景下通常更高效。
- 字符串列类型优化
数据中product列是object类型(Polars转为String),将其转为Categorical类型可降低内存占用并加速分组/关联操作:
df_polar = df_polar.with_columns(pl.col('product').cast(pl.Categorical))
转换后再测试窗口函数或分组Join的性能,通常会有明显提升。
- 版本与线程配置
- 确保使用最新版Polars,新版本会持续优化分组、窗口等操作的性能;
- 尝试调整线程数,部分场景下单线程可避免多线程调度开销:
pl.Config.set_threads(1)
内容的提问来源于stack exchange,提问作者Wiama Daya
相关产品推荐
相关产品推荐

