pyspark中的动态布尔连接

时间:2019-12-12 20:19:43

标签: pyspark

我有两个具有以下相同架构的pyspark数据框-

df_source:

id, name, age

df_target:

id,name,age

“ id”是表中的主列,其余均为属性列

我接受以下用户的主要和属性列列表-

primary_columns = ["id"]
attribute_columns = ["name","age"]

我需要按如下所示动态地连接上述两个数据框-

df_update = df_source.join(df_target, (df_source["id"] == df_target["id"]) & ((df_source["name"] != df_target["name"]) | (df_source["age"] != df_target["age"]))  ,how="inner").select([df_source[col] for col in df_source.columns])

由于属性和主键列的数量可以根据用户输入进行更改,我如何在pyspark中动态实现此连接条件?请帮忙。

1 个答案:

答案 0 :(得分:0)

IIUC,您只需使用primary_columns上的内部联接和在where上循环的attribute_columns子句即可获得所需的输出。

由于两个DataFrame具有相同的列名,因此使用alias来区分join之后的列名。

from functools import reduce
from pyspark.sql.functions import col

df_update = df_source.alias("s")\
    .join(df_target.alias("t"), on=primary_columns, how="inner")\
    .where(
         reduce(
             lambda a, b: a|b, 
             [(col("s."+c) != col("t."+c) for c in attribute_columns]
         )\
    )
    .select("s.*")

使用reduce可以对attribute_columns中的列应用按位或运算。