如何使用原生表达式 API 在 Polars 中生成项目组合?

How would I generate combinations of items within Polars using the native expression API?

提问人:Thomas 提问时间:10/25/2023 更新时间:10/25/2023 访问量:103

问:

有没有办法在 Polars 列内的列表中生成项目的组合,而无需对每一行使用 + itertools.map_elements()

这是我目前的解决方案:

import polars as pl
import itertools

(pl.DataFrame({'col': [['a', 'b', 'c']]})
   .with_columns(pl.col('col')
                   .map_elements(lambda list_o_things: [sorted((thing_1, thing_2))
                                                        for thing_1, thing_2 
                                                        in itertools.combinations(list_o_things, 2)])
                )
)

这将返回以下内容:

[['a', 'b'], ['a', 'c'], ['b', 'c']]

列表 python-itertools 蟒蛇极地

评论

1赞 jqurious 10/25/2023
旁注:您可以修改“显示”设置,例如 pl。Config(fmt_table_cell_list_len=-1, fmt_str_lengths=120) 来帮助查看完整结果。
0赞 BallpointBen 10/25/2023
你真的希望所有内容都在列表类型的列中,而不是带有元素的长列中吗?
0赞 jqurious 10/25/2023
对于功能请求来说,原生 Rust 版本也可能是一个不错的建议。.list.combinations()
0赞 Thomas 10/25/2023
jqurious - 谢谢,Config 参数非常有用。并且刚刚添加了该功能请求!圆珠笔Ben - 我可能会在之后爆炸它,或者做其他事情,但只是想保持示例简单,但欢迎所有建议!假设我不知道最佳实践。

答:

1赞 Dean MacGregor 10/25/2023 #1

分解嵌套结构,与自身进行交叉连接,过滤掉冗余条目,连接到列表,然后内爆到嵌套列表。

df=pl.DataFrame({'col': [['a', 'b', 'c']]})
(
    df
    .explode('col')
    .join(
        df.explode('col'), how='cross')
    .filter(pl.col('col')<pl.col('col_right'))
    .select(pl.concat_list('col','col_right').implode())
    )
shape: (1, 1)
┌──────────────────────────────────────┐
│ col                                  │
│ ---                                  │
│ list[list[str]]                      │
╞══════════════════════════════════════╡
│ [["a", "b"], ["a", "c"], ["b", "c"]] │
└──────────────────────────────────────┘

评论

0赞 Thomas 10/25/2023
棒!谢谢!
0赞 Thomas 10/25/2023
当(看起来像中断流)时,这会炸毁我的记忆,对于比内存数据集更大的数据集,有没有更好的方法可以做到这一点?.collect(streaming=True).write_parquet('file.parquet').list().concat()
0赞 Dean MacGregor 10/25/2023
中断流媒体并阻止工作的东西是线路。如果注释掉,则可以将结果流式传输到文件中。也许您可以保存一个中间文件,然后在单独的步骤中读取该文件并将列捣碎在一起。sink_parquet.select()