如何在Polars中全连接/合并两个DataFrame并使用右侧数据更新左侧对应值?
如何在Polars中全连接/合并两个DataFrame并使用右侧数据更新左侧对应值?
看起来你遇到的问题是因为误用了所有共同列作为连接键,导致即使是同一个track_name,只要其他列(比如yield)存在差异,就会被判定为不同行,最终full join后出现了重复的8CEB45v1条目。要实现「右侧数据覆盖左侧对应行」的需求,我们需要调整连接逻辑,只以唯一标识列(比如track_name)作为匹配依据,再合并列时优先保留右侧的值。
下面提供两种实用的解决方案:
方法一:Full Join + Coalesce合并列
这种方法先基于唯一主键做全连接,再通过coalesce函数让右侧列值优先覆盖左侧,逻辑清晰且可控:
import polars as pl left_csv = b""" track_name,type,yield,group 8CEB45v1,corn,0.146957,A A188v2,corn,0.86308,A B73v6,corn,0.326076,A CI6621v1,sweetcorn,0.0357792,A CML103v1,sweetcorn,0.510464,A """.strip() right_csv = b""" track_name,type,yield,group 8CEB45v1,corn,0.999,A B1234,pepper,1,B B1235,pepper,2,B """.strip() left = pl.read_csv(left_csv) right = pl.read_csv(right_csv) # 仅使用track_name作为唯一连接键 join_key = "track_name" full_df = left.join( right, on=join_key, how="full", suffix="_right" # 给右侧重复列加后缀区分 ).select( join_key, # 对每一列,优先取右侧的值,右侧无值则保留左侧 pl.coalesce("type_right", "type").alias("type"), pl.coalesce("yield_right", "yield").alias("yield"), pl.coalesce("group_right", "group").alias("group") ) print(full_df)
运行后就能得到你想要的结果:
shape: (7, 4) ┌────────────┬───────────┬───────────┬───────┐ │ track_name ┆ type ┆ yield ┆ group │ │ --- ┆ --- ┆ --- ┆ --- │ │ str ┆ str ┆ f64 ┆ str │ ╞════════════╪═══════════╪═══════════╪═══════╡ │ 8CEB45v1 ┆ corn ┆ 0.999 ┆ A │ │ A188v2 ┆ corn ┆ 0.86308 ┆ A │ │ B73v6 ┆ corn ┆ 0.326076 ┆ A │ │ CI6621v1 ┆ sweetcorn ┆ 0.0357792 ┆ A │ │ CML103v1 ┆ sweetcorn ┆ 0.510464 ┆ A │ │ B1234 ┆ pepper ┆ 1.0 ┆ B │ │ B1235 ┆ pepper ┆ 2.0 ┆ B │ └────────────┴───────────┴───────────┴───────┘
方法二:Concat + Unique(更简洁)
如果你的需求就是「右侧数据覆盖左侧同主键行」,可以直接拼接两个DataFrame后去重,保留最后出现的行(也就是右侧的行),代码更简洁:
full_df = pl.concat([left, right]).unique(subset="track_name", keep="last") print(full_df)
这个方法的逻辑很直观:把左侧数据放在前面,右侧数据放在后面,然后按track_name去重,保留最后一次出现的条目,自然就实现了右侧对左侧的更新。运行结果和方法一完全一致。
为什么你的原代码没生效?
你之前用matching_columns = list(set(left.columns) & set(right.columns))把所有共同列都设为连接键,这意味着只有当track_name、type、yield、group四列的值完全相同时,才会合并行。而右侧的8CEB45v1的yield值和左侧不同,所以被判定为不同行,导致full join后出现了重复条目。核心问题就是要使用唯一标识列作为连接键,而非所有共同列。
备注:内容来源于stack exchange,提问作者Pm740
相关产品推荐
相关产品推荐

