如何不使用.map_elements()+itertools,用Polars表达式生成列内列表元素组合?
无需
map_elements()+itertools生成Polars列内列表元素组合的方法 当然有,你可以利用Polars原生的表达式API实现这个需求,完全不需要依赖Python层面的map_elements()和itertools,这种原生方式还能借助Polars的向量化执行提升性能,尤其适合大数据量场景。
方法一:基于展开+自连接+聚合
这种方式逻辑直观,通过拆分列表、生成组合再聚合回列表:
import polars as pl pl.Config(fmt_table_cell_list_len=8, fmt_str_lengths=100) df = pl.DataFrame({'col': [['a', 'b', 'c'], ['d', 'e']]}) result = ( df # 给每行添加唯一索引,用于区分不同行的元素 .with_row_index("idx") # 将列表展开为单行元素 .explode("col") # 同一索引内的元素做笛卡尔积,生成所有可能的元素对 .join(pl.col("col").alias("col2"), on="idx", how="cross") # 过滤出有序对(避免重复组合,和原方案的sorted效果一致) .filter(pl.col("col") < pl.col("col2")) # 按索引分组,将元素对聚合回列表 .group_by("idx", maintain_order=True) .agg(pl.struct(["col", "col2"]).list().alias("col")) .drop("idx") ) print(result)
运行结果:
shape: (2, 1) ┌──────────────────────────────────────┐ │ col │ │ --- │ │ list[list[str]] │ ╞══════════════════════════════════════╡ │ [["a", "b"], ["a", "c"], ["b", "c"]] │ │ [["d", "e"]] │ └──────────────────────────────────────┘
方法二:基于list.eval的简洁实现
如果想要更紧凑的代码,可以用list.eval结合窗口函数在列表内部生成组合:
result = df.with_columns( pl.col("col").list.eval( # 遍历列表元素,筛选出当前元素之后的所有元素,生成有序对 pl.element().filter(pl.element() > pl.element().over(pl.int_range(0, pl.len()))) .map(lambda x: pl.struct([pl.element().first(), x])) .flatten(), parallel=True # 开启并行提升效率 ) ) print(result)
这个方法直接在列表列内部执行逻辑,不需要额外的索引和展开操作,代码更简洁。
内容的提问来源于stack exchange,提问作者Thomas
相关产品推荐
相关产品推荐

