Apache spark 在PySpark中以列表形式动态生成连接条件时,如何应用;或;在元素之间,而不是;“和”;?
我正在连接两个数据帧site_bs和site_wrk_int1,并使用动态连接条件创建site_wrk 我的代码如下:Apache spark 在PySpark中以列表形式动态生成连接条件时,如何应用;或;在元素之间,而不是;“和”;?,apache-spark,pyspark,apache-spark-sql,Apache Spark,Pyspark,Apache Spark Sql,我正在连接两个数据帧site_bs和site_wrk_int1,并使用动态连接条件创建site_wrk 我的代码如下: join_cond=[ col(v_col) == col('wrk_'+v_col) for v_col in primaryKeyCols] #result would be site_wrk=site_bs.join(site_wrk_int1,join_cond,'inner').select(*site_bs.columns) join_cond将是动态的,其值
join_cond=[ col(v_col) == col('wrk_'+v_col) for v_col in primaryKeyCols] #result would be
site_wrk=site_bs.join(site_wrk_int1,join_cond,'inner').select(*site_bs.columns)
join_cond将是动态的,其值类似于[col(id)=col(wrk_id),col(id)=col(wrk_parentId)]
在上述连接条件中,连接将在满足上述两个条件的情况下发生。i、 例如,连接条件将为
id = wrk_id and id = wrk_parentId
但我希望或条件应用如下
id = wrk_id or id = wrk_parentId
如何在Pyspark中实现这一点?我对spark SQL非常陌生。 如果这是一个解决方案,请通知我
site_wrk = site_bs.join(site_work_int1, [(site_bs.id == site_work_int1.wrk_id) | (site_bs.id == site_work_int1.wrk_parentId)], how = "inner")
由于
pyspark
列上的逻辑操作返回列对象,因此可以在join语句中链接这些条件,例如:
from pyspark.sql import SparkSession
import pyspark.sql.functions as f
spark = SparkSession.builder.getOrCreate()
df = spark.createDataFrame([
(1, "A", "A"),
(2, "C", "C"),
(3, "E", "D"),
], ['id', 'col1', 'col2']
)
df.show()
+---+----+----+
| id|col1|col2|
+---+----+----+
| 1| A| A|
| 2| C| C|
| 3| E| D|
+---+----+----+
df.alias("t1").join(
df.alias("t2"),
(f.col("t1.col1") == f.col("t2.col2")) | (f.col("t1.col1") == f.lit("E")),
"left_outer"
).show(truncate=False)
+---+----+----+---+----+----+
|id |col1|col2|id |col1|col2|
+---+----+----+---+----+----+
|1 |A |A |1 |A |A |
|2 |C |C |2 |C |C |
|3 |E |D |1 |A |A |
|3 |E |D |2 |C |C |
|3 |E |D |3 |E |D |
+---+----+----+---+----+----+
如您所见,对于ID为1和2的左行,我得到的True
值为col1==col2或col1==E
,对于我的数据帧的三行,这是True
。在语法方面,Python操作符(|&…
)必须用闭括号分隔,如上面的示例所示,否则可能会出现混淆的py4j
错误
或者,如果您希望保持问题中所述的类似符号,为什么不使用functools.reduce
和运算符。或
将此逻辑应用于列表,例如:
在本例中,我的列条件和getNULL
条件之间有一个和
条件,正如预期的那样:
df.alias("t1").join(
df.alias("t2"),
[f.col("t1.col1") == f.col("t2.col2"), f.col("t1.col1") == f.lit("E")],
"left_outer"
).show(truncate=False)
+---+----+----+----+----+----+
|id |col1|col2|id |col1|col2|
+---+----+----+----+----+----+
|3 |E |D |null|null|null|
|1 |A |A |null|null|null|
|2 |C |C |null|null|null|
+---+----+----+----+----+----+
在本例中,我利用functools
和operator
获得与上面相同的结果:
df.alias("t1").join(
df.alias("t2"),
functools.reduce(
operator.or_,
[f.col("t1.col1") == f.col("t2.col2"), f.col("t1.col1") == f.lit("E")]),
"left_outer"
).show(truncate=False)
+---+----+----+---+----+----+
|id |col1|col2|id |col1|col2|
+---+----+----+---+----+----+
|1 |A |A |1 |A |A |
|2 |C |C |2 |C |C |
|3 |E |D |1 |A |A |
|3 |E |D |2 |C |C |
|3 |E |D |3 |E |D |
+---+----+----+---+----+----+
接线员是我要找的人。谢谢你,拿破仑。