如何在Polars中无需遍历列应用返回DataFrame的函数(含双DataFrame场景)
Polars 列操作优化:避免遍历列的两种场景实现
场景1:将返回DataFrame的函数批量应用到所有列
原代码通过遍历列调用get_rolling_mean生成多个DataFrame列表,大数据集下Python循环开销明显。利用Polars的pl.all().map()方法,可直接对所有列批量处理并自动合并结果,完全规避循环开销。
优化后代码:
import polars as pl import numpy as np df = pl.DataFrame({ 'A': np.random.randint(0, 10, 20), 'B': np.random.randint(20, 30, 20), }) def get_rolling_mean(series, windows=[1,2,3]): # 给结果列加原列名前缀,避免重复列名 rolling_means = [series.rolling_mean(window).alias(f'{series.name}_{window}') for window in windows] return pl.DataFrame(rolling_means) # 无循环实现:对所有列批量应用函数,自动合并结果 df_rolling_means = df.select(pl.all().map(get_rolling_mean))
说明:pl.all()选中所有列,map()对每列执行get_rolling_mean,返回的每个DataFrame会被自动展开合并成最终结果,列名格式为原列名_窗口大小,可读性更强。
场景2:两个DataFrame对应列传入函数生成信号
原代码遍历列对df_high和df_low的对应列调用get_signal,效率低下。利用Polars的zip_with()方法,可将两个DataFrame的同名列一一配对,批量传入函数处理,无需手动遍历。
优化后代码:
import polars as pl import numpy as np df_high = pl.DataFrame({ 'A': np.random.randint(0, 10, 20), 'B': np.random.randint(20, 30, 20), }) df_low = pl.DataFrame({ 'A': np.random.randint(0, 10, 20), 'B': np.random.randint(20, 30, 20), }) def get_signal(high_series, low_series, params): # 示例计算:高低差值乘以参数系数,可替换为实际业务逻辑 return (high_series - low_series) * params['coef'] PARAMS = {'coef': 2} # 无循环实现:配对对应列并批量处理 signals_df = df_high.select( pl.all().zip_with(df_low.select(pl.all()), lambda h, l: get_signal(h, l, PARAMS)).name.suffix('_signal') )
说明:zip_with()将df_high和df_low的同名列一一配对,传入lambda函数调用get_signal,最后给结果列加_signal后缀区分。整个过程由Polars内部优化执行,比Python循环效率提升显著。
内容的提问来源于stack exchange,提问作者Wazir Kahar
相关产品推荐
相关产品推荐

