我有两个具有以下相同架构的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中动态实现此连接条件?请帮忙。
答案 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
中的列应用按位或运算。