如何提升Polars中行级map_elements操作的运行效率?
问题
我们正计划从DataFlow+Numpy切换至Polars作为核心数据处理框架,但当前部分行级转换操作无法通过Numpy或Polars表达式实现向量化。目前可行的方案是调用map_elements(原apply方法),将Polars列表/数组转换为Numpy格式后传入Python函数,但该方式运行极慢,推测原因有两点:
- 存在数据传输开销
- Polars仅使用单核心
我们清楚所有数据框架均建议尽量避免使用apply类方法,但当前确实属于必须使用的场景,因此希望了解可行的优化方案。VAEX声称调用apply时会启用多进程,但Polars暂无此功能。Polars官方文档的多进程页面仅提供基础示例,且序列化/反序列化(尝试过Arrow格式)耗时过长。
我们想了解Polars用户如何优化map_elements的应用,是否存在未文档化的新特性,以及如何高效地在主进程与子进程间传递DataFrame分片。
已实现的多进程优化方案
感谢@jqurious的提示,我们已实现行级操作的多进程处理,代码如下:
def parallel_apply(func, iterable, chunksize=1): python_iterable = list(iterable.to_numpy()) with multiprocessing.get_context("spawn").Pool(processes=processes) as pool: result = pool.imap(func, track(python_iterable), chunksize) return pl.Series(result)
总结几点实践经验:
to_numpy()比to_list()快一个数量级,转换为Python可迭代对象节省了40%的运行时间;- 较小的chunk size效果更佳(可能与每行的大型Numpy矩阵有关);
to_numpy()会将列表序列转换为数组的数组(因数组大小可变),因此可能需要后续处理(如堆叠)。
内容的提问来源于stack exchange,提问作者Sergii Makarevych
相关产品推荐
相关产品推荐

