Apache spark 在火花上或火花中处理连接
我有这样一个数据框:Apache spark 在火花上或火花中处理连接,apache-spark,join,apache-spark-sql,Apache Spark,Join,Apache Spark Sql,我有这样一个数据框: +---+---+---+---+---+ |AId| A1| A2| A3| A4| +---+---+---+---+---+ | 1| *| a| b| c| | 2| *| *| b| c| | 3| c| a| b| c| | 4| *| *| *| c| | 5| *| *| *| *| +---+---+---+---+---+ 我想参加以下活动: +---+---+---+---+---+----+ |BI
+---+---+---+---+---+
|AId| A1| A2| A3| A4|
+---+---+---+---+---+
| 1| *| a| b| c|
| 2| *| *| b| c|
| 3| c| a| b| c|
| 4| *| *| *| c|
| 5| *| *| *| *|
+---+---+---+---+---+
我想参加以下活动:
+---+---+---+---+---+----+
|BId| B1| B2| B3| B4|Code|
+---+---+---+---+---+----+
| 1| c| a| b| c| AO|
| 2| b| a| b| c| AS|
| 3| b| b| b| c| AT|
| 4| a| d| d| c| BO|
| 5| d| a| c| b| BS|
| 6| a| b| b| c| BT|
| 7| d| d| d| c| CO|
| 8| d| d| d| d| CS|
+---+---+---+---+---+----+
将ID与规则匹配。但是,*是一个通配符。它可以匹配任何东西。在上面的示例中,AId==1将匹配BId 1和2,AId==3将仅匹配BId 1,AId==4将匹配除5和8之外的所有项目,AId==5将匹配所有8个项目
最好的方法是什么?这个查询在Spark中似乎很昂贵,而且Spark没有内置的。另一种选择似乎是A1-A4设置一个标志,然后返回并加入。另一个棘手的问题是,通配符可能会在第一个表的任何列中出现1-4次,尽管它们不会出现在第二个表中。您可以将连接条件表示为:
(A1 = * | (A1 = B1)) AND (A2 = * | (A2 = B2)) AND ... AND (AN = * | (AN = BN))
例如,使用PySpark可以生成如下等效表达式
从pyspark.sql.functions导入col
从functools导入reduce
从操作员导入和_
expr=减少(
而且,,
((col(“A{}.format(i))==“*”))(col(“A{}.format(i))==col(“B{}.format(i)))
对于(1,5)范围内的i)
列
并与交叉连接一起使用:
a.交叉连接(b).其中(expr)
或
spark.conf.set(“spark.sql.crossJoin.enabled”,“true”)
a、 加入(b,expr)
不幸的是,由于笛卡尔积,这相当昂贵。对于少量的列(4可能是一种边界情况),您可以尝试生成一组列并创建优化的计划,但显然它不会扩展到更多的列