Python Polars中处理List[int]类型列的优化方案咨询
优化Polars中List[int]类型列的处理方案
核心优化思路:用Polars原生列表函数替代map_elements
Polars内置了一系列针对列表类型的矢量化操作函数,完全可以替代低效的map_elements,既保留并行计算优势,又避免性能损耗。针对你的需求,直接通过list.concat合并组内列表,再用list.median计算中位数即可:
import polars as pl df = pl.DataFrame( {"group": ["A", "A", "B", "B", "B", "B"], "value": [[3, 2, 5], [2,2,2], [2,5,9,4], [5,4,7,5,1], [9,4,5], [2,2]]} ) result = ( df .group_by("group") .agg( # 合并组内所有列表为一个大列表 merged_values=pl.col("value").list.concat(), # 直接计算合并后列表的中位数,一步完成 median_value=pl.col("value").list.concat().list.median() ) ) print(result)
输出结果:
shape: (2, 3) ┌───────┬──────────────────────────┬──────────────┐ │ group ┆ merged_values ┆ median_value │ │ --- ┆ --- ┆ --- │ │ str ┆ list[i64] ┆ f64 │ ╞═══════╪══════════════════════════╪══════════════╡ │ A ┆ [3, 2, 5, 2, 2, 2] ┆ 2.0 │ │ B ┆ [2, 5, 9, 4, 5, 4, 7, 5… ┆ 4.5 │ └───────┴──────────────────────────┴──────────────┘
该方案高效的原因
- 原生并行计算:
list.concat和list.median都是Polars的内置矢量化操作,能充分利用Polars的并行引擎,性能比Python lambda快数倍甚至数十倍。 - 代码简洁:聚合阶段直接完成合并与统计计算,无需拆分多步,避免冗余代码。
- 低资源开销:全程在Polars内部数据结构中处理,无需转换为Python对象,内存消耗更低。
扩展:其他常见列表列处理场景
针对列表列的其他统计需求,同样可以用Polars的list.*系列函数实现:
- 计算组内所有列表元素总和:
pl.col("value").list.concat().list.sum() - 计算组内所有列表元素均值:
pl.col("value").list.concat().list.mean() - 计算组内所有列表元素最大值:
pl.col("value").list.concat().list.max() - 统计组内所有列表元素总数:
pl.col("value").list.concat().list.len()
替代方案:简化explode写法
如果习惯用explode处理,也可以通过链式调用简化代码,性能同样优秀:
result = ( df .explode("value") .group_by("group") .agg( median_value=pl.col("value").median(), all_values=pl.col("value").list() # 可选:保留所有元素的列表 ) )
这个方案适合需要同时查看原始元素和统计结果的场景,explode本身也是Polars的矢量化操作,不会有性能瓶颈。
内容的提问来源于stack exchange,提问作者Alk90
相关产品推荐
相关产品推荐

