我有一个 Polars Dataframe,我想信任一个新的 Dataframe,它由所有可能的组合组成,从每行中选择 1 个元素。
视觉上是这样的:
输入数据框
| Column A | Column B | Column C |
| -------- | -------- | -------- |
| A1 | B1 | C1 |
| A2 | B2 | C2 |
| A3 | B3 | C3 |
会给
| Column A | Column B | Column A |
| -------- | -------- | -------- |
| A1 | A2 | A3 |
| A1 | A2 | B3 |
| A1 | A2 | C3 |
| A1 | B2 | A3 |
| A1 | B2 | B3 |
| A1 | B2 | C3 |
| A1 | C2 | A3 |
| A1 | C2 | B3 |
| A1 | C2 | C3 |
| B1 | A2 | A3 |
| B1 | A2 | B3 |
| B1 | A2 | C3 |
| B1 | B2 | A3 |
| B1 | B2 | B3 |
| B1 | B2 | C3 |
| B1 | C2 | A3 |
| B1 | C2 | B3 |
| B1 | C2 | C3 |
等等...
我尝试通过简单地使用 2D 数组和双 for 循环来实现这一点,这相当简单,但是,我真的很想使用 Polars 的 Dataframes 来实现这一点,并符合 Polars 的构建方式,正如我所希望的那样它的计算速度比双 for 循环快得多。这个库对我来说仍然相当新,所以如果我有某种误解,请告诉我。
据我所知,没有直接的“组合”功能。
一种可能的方法是
.implode()
然后 .explode()
每列。
df = pl.from_repr("""
┌──────────┬──────────┬──────────┐
│ Column A ┆ Column B ┆ Column C │
│ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str │
╞══════════╪══════════╪══════════╡
│ A1 ┆ B1 ┆ C1 │
│ A2 ┆ B2 ┆ C2 │
│ A3 ┆ B3 ┆ C3 │
└──────────┴──────────┴──────────┘
""")
(df.select(pl.all().implode())
.explode("Column A")
.explode("Column B")
.explode("Column C")
)
shape: (27, 3)
┌──────────┬──────────┬──────────┐
│ Column A ┆ Column B ┆ Column C │
│ --- ┆ --- ┆ --- │
│ str ┆ str ┆ str │
╞══════════╪══════════╪══════════╡
│ A1 ┆ B1 ┆ C1 │
│ A1 ┆ B1 ┆ C2 │
│ A1 ┆ B1 ┆ C3 │
│ A1 ┆ B2 ┆ C1 │
│ … ┆ … ┆ … │
│ A3 ┆ B2 ┆ C3 │
│ A3 ┆ B3 ┆ C1 │
│ A3 ┆ B3 ┆ C2 │
│ A3 ┆ B3 ┆ C3 │
└──────────┴──────────┴──────────┘
如果有重复值,您可以添加
.unique()
。
您可以使用 Lazy API 和循环,而不必命名每一列:
out = df.lazy().select(pl.all().implode())
for col in df.columns:
out = out.explode(col)
out.collect()