基于ID和多列找出两个Polars DataFrame的差异行
解决Polars DataFrame基于双键对比差异的问题
核心解决思路是同时用ID和Iname作为连接键,而非仅依赖ID,这样能确保只有两个键完全匹配的行才会被关联,彻底避免你之前遇到的Iname不匹配错误对比的问题。
步骤1:基于ID+Iname做全连接
先将两个DataFrame按ID和Iname执行全连接,这样会保留所有仅在df1或仅在df2中存在的行,同时把双键匹配的行合并到同一行。为了区分两个表的列,给df1的列加_df1后缀,df2的列加_df2后缀:
import polars as pl # 示例测试数据 df1 = pl.DataFrame({ "ID": [1, 2, 3], "Iname": ["foo", "bar", "baz"], "X": [10, 20, 30], "Y": [100, 200, 300], "Z": [1000, 2000, 3000] }) df2 = pl.DataFrame({ "ID": [1, 2, 4], "Iname": ["foo", "baz", "qux"], "X": [10, 25, 40], "Y": [100, 220, 400], "Z": [1000, 2300, 4000] }) # 执行全连接并添加列后缀区分来源 joined_df = df1.join( df2, on=["ID", "Iname"], how="full", suffix="_df2" ).rename({col: f"{col}_df1" for col in df1.columns if col not in ["ID", "Iname"]})
步骤2:筛选存在差异的行
筛选以下两类差异行:
- 仅在单表存在的行(即某一侧的X/Y/Z列为null)
- X、Y、Z列中至少有一列值不相等的行
# 定义差异判断条件 diff_condition = ( pl.col("X_df1") != pl.col("X_df2") | pl.col("Y_df1") != pl.col("Y_df2") | pl.col("Z_df1") != pl.col("Z_df2") | pl.col("X_df1").is_null() | pl.col("X_df2").is_null() ) # 筛选出所有差异行 diff_result = joined_df.filter(diff_condition)
可选:优化结果展示格式
如果需要更直观的差异说明,可以新增一列标记差异类型:
diff_result = diff_result.with_columns( pl.when(pl.col("X_df1").is_null()) .then(pl.lit("仅在df2存在")) .when(pl.col("X_df2").is_null()) .then(pl.lit("仅在df1存在")) .otherwise(pl.lit("值存在差异")) .alias("差异类型") )
最终结果会精准保留所有符合要求的差异行,不会出现Iname不匹配的错误关联情况。
内容的提问来源于stack exchange,提问作者Simon
相关产品推荐
相关产品推荐

