Polars中的Pandas合并功能

2 投票
3 回答
94 浏览
提问于 2025-04-14 16:20

我想把两个Polars数据框合并在一起(可能是基于多个列),而且合并时用来匹配的列不想重复出现。

现在的情况是:

>>> a 
shape: (3, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞═════╪═════╡
│ 1   ┆ 1   │
│ 2   ┆ 2   │
│ 3   ┆ 3   │
└─────┴─────┘
>>> b
shape: (3, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞═════╪═════╡
│ 3   ┆ 3   │
│ 4   ┆ 4   │
│ 5   ┆ 5   │
└─────┴─────┘
>>> a.join(b, how='outer', on='a')
shape: (5, 4)
┌──────┬──────┬─────────┬─────────┐
│ a    ┆ b    ┆ a_right ┆ b_right │
│ ---  ┆ ---  ┆ ---     ┆ ---     │
│ i64  ┆ i64  ┆ i64     ┆ i64     │
╞══════╪══════╪═════════╪═════════╡
│ 3    ┆ 3    ┆ 3       ┆ 3       │
│ null ┆ null ┆ 4       ┆ 4       │
│ null ┆ null ┆ 5       ┆ 5       │
│ 1    ┆ 1    ┆ null    ┆ null    │
│ 2    ┆ 2    ┆ null    ┆ null    │
└──────┴──────┴─────────┴─────────┘

我想要的结果是:

>>> a 
shape: (3, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞═════╪═════╡
│ 1   ┆ 1   │
│ 2   ┆ 2   │
│ 3   ┆ 3   │
└─────┴─────┘
>>> b
shape: (3, 2)
┌─────┬─────┐
│ a   ┆ b   │
│ --- ┆ --- │
│ i64 ┆ i64 │
╞═════╪═════╡
│ 3   ┆ 3   │
│ 4   ┆ 4   │
│ 5   ┆ 5   │
└─────┴─────┘
>>> <what command goes here>
shape: (5, 3)
┌─────┬──────┬──────┐
│ a   ┆ b_x  ┆ b_y  │
│ --- ┆ ---  ┆ ---  │
│ i64 ┆ f64  ┆ f64  │
╞═════╪══════╪══════╡
│ 1   ┆ 1.0  ┆ null │
│ 2   ┆ 2.0  ┆ null │
│ 3   ┆ 3.0  ┆ 3.0  │
│ 4   ┆ null ┆ 4.0  │
│ 5   ┆ null ┆ 5.0  │
└─────┴──────┴──────┘

我希望这样做,因为我有很大的数据框需要在多个列上进行合并。有一种可能的方法是先把用来匹配的列合并起来,然后再去掉重复的列,但这样做感觉有点麻烦。

3 个回答

0

你可以使用一种叫做“outer_coalesce”的连接方式来实现这种类型的连接(需要使用python polars 0.20.14或更高版本)。这种连接方式和“outer”连接类似,不同之处在于它会合并索引列。举个例子:

>>> df1 = pl.DataFrame(dict(a=[1,2,3], b=[1,2,3]))
>>> df2 = pl.DataFrame(dict(a=[3,4,5], b=[3,4,5]))

>>> df1.join(df2, on="a", how="outer_coalesce", suffix="_y")\
       .rename({"b": "b_x"}).sort("a")

shape: (5, 3)
┌─────┬──────┬──────┐
│ a   ┆ b_x  ┆ b_y  │
│ --- ┆ ---  ┆ ---  │
│ i64 ┆ i64  ┆ i64  │
╞═════╪══════╪══════╡
│ 1   ┆ 1    ┆ null │
│ 2   ┆ 2    ┆ null │
│ 3   ┆ 3    ┆ 3    │
│ 4   ┆ null ┆ 4    │
│ 5   ┆ null ┆ 5    │
└─────┴──────┴──────┘
1

你可以使用 outer_coalesce 这种方法来进行 join 操作:

(
    a.join(b, how='outer_coalesce', on='a', suffix='_y')
    .rename({'b':'b_x'})
    .sort('a')
)

┌─────┬──────┬──────┐
│ a   ┆ b_x  ┆ b_y  │
│ --- ┆ ---  ┆ ---  │
│ i64 ┆ i64  ┆ i64  │
╞═════╪══════╪══════╡
│ 1   ┆ 1    ┆ null │
│ 2   ┆ 2    ┆ null │
│ 3   ┆ 3    ┆ 3    │
│ 4   ┆ null ┆ 4    │
│ 5   ┆ null ┆ 5    │
└─────┴──────┴──────┘

我还添加了 rename()sort() 方法,以便得到想要的结果。

3

pl.DataFrame.join 里的 how 参数设置为 "outer_coalesce",就能得到我们想要的数据表。

a.join(b, on="a", how="outer_coalesce").sort("a")
shape: (5, 3)
┌─────┬──────┬─────────┐
│ a   ┆ b    ┆ b_right │
│ --- ┆ ---  ┆ ---     │
│ i64 ┆ i64  ┆ i64     │
╞═════╪══════╪═════════╡
│ 1   ┆ 1    ┆ null    │
│ 2   ┆ 2    ┆ null    │
│ 3   ┆ 3    ┆ 3       │
│ 4   ┆ null ┆ 4       │
│ 5   ┆ null ┆ 5       │
└─────┴──────┴─────────┘

根据说明:

和‘outer’一样,但会合并关键列。

注意。 最后的 sort("a") 只是为了让结果按预期的顺序排列。

撰写回答