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

如何定位两个Polars DataFrame之间的差异?

定位Polars DataFrame差异的方法

针对你的需求,以下是高效定位并标记/过滤差异行的方案,适配多列场景:

1. 先关联两个DataFrame(你已完成此步骤)

import polars as pl

df1 = pl.DataFrame([
    {'id': 1,'col1': ['a',None],'col2': ['x']},
    {'id': 2,'col1': ['b'],'col2': ['y', None]},
    {'id': 3,'col1': [None],'col2': ['z']}]
)

df2 = pl.DataFrame([
    {'id': 1,'col1': ['a'],'col2': ['x']},
    {'id': 2,'col1': ['b', None],'col2': ['y', None]},
    {'id': 3,'col1': [None],'col2': ['z']}]
)

# 按id关联,添加后缀区分两个DataFrame的列
joined_df = df1.join(df2, on='id', suffix='_df2')

2. 自动生成差异判断逻辑

因为实际列数多,我们可以通过列名自动匹配需要对比的列对,避免手动逐个编写:

# 获取除id外的所有原列
original_cols = [col for col in df1.columns if col != 'id']
# 生成每列的差异判断条件:原列 vs df2对应列
diff_conditions = [pl.col(col) != pl.col(f"{col}_df2") for col in original_cols]

3. 方案一:添加布尔列标记差异行

给每行添加has_difference列,标记该行是否存在任意列差异:

result_with_flag = joined_df.with_columns(
    has_difference=pl.any_horizontal(diff_conditions)
)

输出结果:

┌─────┬─────────────┬─────────────┬─────────────┬─────────────┬───────────────┐
│ id  ┆ col1        ┆ col2        ┆ col1_df2    ┆ col2_df2    ┆ has_difference│
│ --- ┆ ---         ┆ ---         ┆ ---         ┆ ---         ┆ ---           │
│ i64 ┆ list[str]   ┆ list[str]   ┆ list[str]   ┆ list[str]   ┆ bool          │
╞═════╪═════════════╪═════════════╪═════════════╪═════════════╪═══════════════╡
│ 1   ┆ ["a", null] ┆ ["x"]       ┆ ["a"]       ┆ ["x"]       ┆ true          │
│ 2   ┆ ["b"]       ┆ ["y", null] ┆ ["b", null] ┆ ["y", null] ┆ true          │
│ 3   ┆ [null]      ┆ ["z"]       ┆ [null]      ┆ ["z"]       ┆ false         │
└─────┴─────────────┴─────────────┴─────────────┴─────────────┴───────────────┘

4. 方案二:直接过滤出差异行

仅保留存在差异的行:

diff_rows = joined_df.filter(pl.any_horizontal(diff_conditions))

输出结果:

┌─────┬─────────────┬─────────────┬─────────────┬─────────────┐
│ id  ┆ col1        ┆ col2        ┆ col1_df2    ┆ col2_df2    │
│ --- ┆ ---         ┆ ---         ┆ ---         ┆ ---         │
│ i64 ┆ list[str]   ┆ list[str]   ┆ list[str]   ┆ list[str]   │
╞═════╪═════════════╪═════════════╪═════════════╪═════════════╡
│ 1   ┆ ["a", null] ┆ ["x"]       ┆ ["a"]       ┆ ["x"]       │
│ 2   ┆ ["b"]       ┆ ["y", null] ┆ ["b", null] ┆ ["y", null] │
└─────┴─────────────┴─────────────┴─────────────┴─────────────┘

进阶:标记具体差异列

如果需要知道每行具体哪些列有差异,可以给每个列添加单独的差异标记:

result_with_col_flags = joined_df.with_columns(
    # 为每个列添加差异标记列
    **{f"{col}_diff": pl.col(col) != pl.col(f"{col}_df2") for col in original_cols},
    # 整体差异标记
    has_difference=pl.any_horizontal(diff_conditions)
)

输出结果:

┌─────┬─────────────┬─────────────┬─────────────┬─────────────┬──────────┬──────────┬───────────────┐
│ id  ┆ col1        ┆ col2        ┆ col1_df2    ┆ col2_df2    ┆ col1_diff┆ col2_diff┆ has_difference│
│ --- ┆ ---         ┆ ---         ┆ ---         ┆ ---         ┆ ---      ┆ ---      ┆ ---           │
│ i64 ┆ list[str]   ┆ list[str]   ┆ list[str]   ┆ list[str]   ┆ bool     ┆ bool     ┆ bool          │
╞═════╪═════════════╪═════════════╪═════════════╪═════════════╪══════════╪══════════╪═══════════════╡
│ 1   ┆ ["a", null] ┆ ["x"]       ┆ ["a"]       ┆ ["x"]       ┆ true     ┆ false    ┆ true          │
│ 2   ┆ ["b"]       ┆ ["y", null] ┆ ["b", null] ┆ ["y", null] ┆ true     ┆ false    ┆ true          │
│ 3   ┆ [null]      ┆ ["z"]       ┆ [null]      ┆ ["z"]       ┆ false    ┆ false    ┆ false         │
└─────┴─────────────┴─────────────┴─────────────┴─────────────┴──────────┴──────────┴───────────────┘

说明

  • Polars中列表类型的!=比较是整体匹配:只有两个列表的元素、长度、null位置完全一致时才会返回False,否则返回True,正好适配你的示例场景。
  • 自动匹配列对的逻辑无需修改代码即可适配任意数量的列,适合你的实际多列数据。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.31 02:27:46