
在 Polars 中对含列表的列进行分组聚合时,若希望将多个子列表拼接为单一扁平列表(而非嵌套列表),应先使用 explode() 展开列表元素,再聚合;agg(pl.col("name").explode()) 即可高效实现扁平化连接。
在 polars 中对含列表的列进行分组聚合时,若希望将多个子列表拼接为单一扁平列表(而非嵌套列表),应先使用 `explode()` 展开列表元素,再聚合;`agg(pl.col("name").explode())` 即可高效实现扁平化连接。
当使用 df.group_by('id').agg('name') 时,Polars 默认将每行的列表作为独立元素收集,导致结果为嵌套结构(如 [["Bob"], ["Mary", "Sue"]])。要获得真正的扁平化合并(即 ["Bob", "Mary", "Sue"]),关键在于先解构再聚合:explode() 将每行列表“打散”为多行单元素记录,随后 agg() 对所有展开后的元素统一收集为一个列表。
以下是完整示例:
import polars as pl
df = pl.DataFrame({
'id': [1, 1],
'name': [["Bob"], ["Mary", "Sue"]],
})
result = df.group_by('id').agg(pl.col('name').explode())
print(result)输出:
shape: (1, 2) ┌─────┬─────────────────────────┐ │ id ┆ name │ │ --- ┆ --- │ │ i64 ┆ list[str] │ ╞═════╪═════════════════════════╡ │ 1 ┆ ["Bob", "Mary", "Sue"] │ └─────┴─────────────────────────┘
✅ 此方法高效、声明式强,且完全利用 Polars 的惰性执行与零拷贝优化。
⚠️ 注意事项:
- explode() 会增加行数(本例中从 2 行变为 3 行),但因在 agg() 内部使用,该中间展开不暴露于最终结果,性能影响极小;
- 若原始列表可能为空([]),explode() 会将其转为零行,不影响聚合结果完整性;
- 不推荐先 apply() 自定义拼接逻辑——这会破坏 Polars 的向量化优势,显著降低性能。
总结:扁平化列表聚合 = group_by(...).agg(pl.col(...).explode()) —— 简洁、正确、符合 Polars 设计哲学。

















