You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Polars地道合并行与列均重叠的DataFrame?

用Polars实现带优先级的DataFrame合并(行/列均重叠场景)

问题背景

有两个DataFrame,共享标识列i,其余列存在重叠(如a)和独有列(如b、c),行和列都有部分重叠,示例代码如下:

import polars as pl
df = pl.DataFrame(
    {
        "i": [1, 2, 3, 4],
        "a": [2.6, 5.3, None, None],
        "b": ["ab", "cd", "ef", "gh"]
    }
)
df2 = pl.DataFrame(
    {
        "i": [2, 3, 5, 6],
        "a": [None, 3.5, 2.5, 0.9],
        "c": [True, False, False, True]
    }
)

现有方法存在的局限:

  • 对角线拼接+unique()会丢失独有的列数据(如i=2的c列值)
  • 全外连接后手动合并重叠列(如a和a_right),列数多时操作繁琐
  • 将重叠列加入on参数会导致同一i但值不同/缺失的行无法合并

期望合并结果:保留每个标识的所有已知数据,可指定单元格的数据源优先级(如优先保留某DataFrame的非空值),最终输出如下:

┌─────┬──────┬──────┬───────┐
│ i   ┆ a    ┆ b    ┆ c     │
│ --- ┆ ---  ┆ ---  ┆ ---   │
│ i64 ┆ f64  ┆ str  ┆ bool  │
╞═════╪══════╪══════╪═══════╡
│ 2   ┆ 5.3  ┆ cd   ┆ true  │
│ 3   ┆ 3.5  ┆ ef   ┆ false │
│ 5   ┆ 2.5  ┆ null ┆ false │
│ 6   ┆ 0.9  ┆ null ┆ true  │
│ 1   ┆ 2.6  ┆ ab   ┆ null  │
│ 4   ┆ null ┆ gh   ┆ null  │
└─────┴──────┴──────┴───────┘

解决方案

通过全外连接+自动合并重叠列的方式实现,可灵活指定数据源优先级:

import polars as pl

# 定义原始DataFrame
df = pl.DataFrame(
    {
        "i": [1, 2, 3, 4],
        "a": [2.6, 5.3, None, None],
        "b": ["ab", "cd", "ef", "gh"]
    }
)
df2 = pl.DataFrame(
    {
        "i": [2, 3, 5, 6],
        "a": [None, 3.5, 2.5, 0.9],
        "c": [True, False, False, True]
    }
)

# 1. 执行全外连接,保留所有行和列,对右表重叠列添加后缀
joined_df = df.join(df2, on="i", how="full", suffix="_right")

# 2. 自动识别并合并重叠列
# 获取除标识列外的重叠列名
overlap_columns = [col for col in df.columns if col in df2.columns and col != "i"]

for col in overlap_columns:
    # 用coalesce指定优先级:优先取左表(df)的非空值,左表为空则取右表(df2)的值
    # 若要优先右表,调换coalesce内的列顺序即可
    joined_df = joined_df.with_columns(
        pl.coalesce([pl.col(col), pl.col(f"{col}_right")]).alias(col)
    ).drop(f"{col}_right")

# 3. 调整列顺序(可选,匹配期望结果)
final_result = joined_df.select(["i", "a", "b", "c"])
print(final_result)

关键说明

  • pl.coalesce():按传入顺序取第一个非空值,通过调整列顺序即可轻松指定数据源优先级
  • 自动遍历重叠列:避免手动处理大量重叠列的繁琐操作
  • 全外连接确保所有行(包括仅在某一个DataFrame中存在的i)都被保留

补充说明

已在GitHub提交issue,建议添加df.supplement()方法,与df.update()互补,优先保留原DataFrame的非空值,仅补充原DataFrame缺失的值并添加新列。


内容的提问来源于stack exchange,提问作者matterhorn103

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.21 17:54:52