Apache spark 对于Spark数据帧中的右外连接,是否有更好的替代方案?以及如何有条件地转换行?
我为一个很长的问题提前道歉。我会尽量用一个简单的例子来解释。我有以下两个数据帧df1和df2Apache spark 对于Spark数据帧中的右外连接,是否有更好的替代方案?以及如何有条件地转换行?,apache-spark,apache-spark-sql,spark-dataframe,Apache Spark,Apache Spark Sql,Spark Dataframe,我为一个很长的问题提前道歉。我会尽量用一个简单的例子来解释。我有以下两个数据帧df1和df2 +---------+-------+-------+ | CATEGORY| REGION| avgCol| +-------- +-------+-------+ | CAT-1| NORTH| 0.575| | CAT-1| SOUTH| 15.879| | CAT-2| NORTH| 5.255| +---------+-------+-------+ df1: +
+---------+-------+-------+
| CATEGORY| REGION| avgCol|
+-------- +-------+-------+
| CAT-1| NORTH| 0.575|
| CAT-1| SOUTH| 15.879|
| CAT-2| NORTH| 5.255|
+---------+-------+-------+
df1:
+------+---------+-------+-------+-------+
| PID| CATEGORY| REGION| VOLUME| RESULT|
+------+-------- +-------+-------+-------+
|123456| CAT-1| NORTH| 200| 1.345|
|123456| CAT-1| SOUTH| 125| 2.890|
|123456| CAT-2| NORTH| 75| 6.755|
|123456| CAT-2| SOUTH| 100| 0.432|
|123456| CAT-3| NORTH| 50| 5.111|
+------+---------+-------+-------+-------+
df2
+---------+-------+-------+
| CATEGORY| REGION| avgCol|
+-------- +-------+-------+
| CAT-1| NORTH| 0.575|
| CAT-1| SOUTH| 15.879|
| CAT-2| NORTH| 5.255|
+---------+-------+-------+
我想加入这两个DFs以获得第三个DF
df3
+------+---------+-------+-------+-------+-------+
| PID| CATEGORY| REGION| avgCol| VOLUME| RESULT|
+------+-------- +-------+-------+-------+-------+
|123456| CAT-1| NORTH| 0.575| 200| 1.345|
|123456| CAT-1| SOUTH| 15.879| 125| 2.890|
|123456| CAT-2| NORTH| 5.255| 75| 6.755|
|123456| CAT-2| SOUTH| null| 100| 0.432|
|123456| CAT-3| NORTH| null| 50| 5.111|
+------+---------+-------+-------+-------+-------+
我用了正确的外部连接。代码看起来像
DataFrame df3 = df1.join(df2, joinCols, "right_outer");
df3.withColumn("NEW_RESULT", when(col("avgCol").isNotNull(), getResult(avgCol).otherwise(col("RESULT"))
.drop("RESULT").withColumnRenamed("NEW_RESULT", "RESULT)
+------+---------+-------+-------+-------+-------+
| PID| CATEGORY| REGION| avgCol| VOLUME| RESULT|
+------+-------- +-------+-------+-------+-------+
|123456| CAT-1| NORTH| 0.575| 200| 8.543|
|123456| CAT-1| SOUTH| 15.879| 125| 4.321|
|123456| CAT-2| NORTH| 5.255| 75| 7.012|
|123456| CAT-2| SOUTH| null| 100| 0.432|
|123456| CAT-3| NORTH| null| 50| 5.111|
+------+---------+-------+-------+-------+-------+
其中,joinCols是我要加入的列的集合
然后,我想将df3转换为一个数据帧,其中RESULT的值仅针对avgCol为空的行新计算。实现这一点的代码如下所示
DataFrame df3 = df1.join(df2, joinCols, "right_outer");
df3.withColumn("NEW_RESULT", when(col("avgCol").isNotNull(), getResult(avgCol).otherwise(col("RESULT"))
.drop("RESULT").withColumnRenamed("NEW_RESULT", "RESULT)
+------+---------+-------+-------+-------+-------+
| PID| CATEGORY| REGION| avgCol| VOLUME| RESULT|
+------+-------- +-------+-------+-------+-------+
|123456| CAT-1| NORTH| 0.575| 200| 8.543|
|123456| CAT-1| SOUTH| 15.879| 125| 4.321|
|123456| CAT-2| NORTH| 5.255| 75| 7.012|
|123456| CAT-2| SOUTH| null| 100| 0.432|
|123456| CAT-3| NORTH| null| 50| 5.111|
+------+---------+-------+-------+-------+-------+
所以df4看起来像
DataFrame df3 = df1.join(df2, joinCols, "right_outer");
df3.withColumn("NEW_RESULT", when(col("avgCol").isNotNull(), getResult(avgCol).otherwise(col("RESULT"))
.drop("RESULT").withColumnRenamed("NEW_RESULT", "RESULT)
+------+---------+-------+-------+-------+-------+
| PID| CATEGORY| REGION| avgCol| VOLUME| RESULT|
+------+-------- +-------+-------+-------+-------+
|123456| CAT-1| NORTH| 0.575| 200| 8.543|
|123456| CAT-1| SOUTH| 15.879| 125| 4.321|
|123456| CAT-2| NORTH| 5.255| 75| 7.012|
|123456| CAT-2| SOUTH| null| 100| 0.432|
|123456| CAT-3| NORTH| null| 50| 5.111|
+------+---------+-------+-------+-------+-------+
注意:我删除并重命名该列作为结果,因为我想在下一次迭代中使用此表
现在,这产生了预期的结果,但没有实现。特别是,当我将这是一个循环,并且连接列的数量不断增加时,连接和后续操作需要很长时间。每次迭代都会变得更糟
我的问题是-是否有更有效的方法在Spark中执行这两个/其中一个操作,最好使用数据帧
我读了几篇文章,建议分析join操作的物理计划,以找到优化的方法,但我从中收集不到太多信息。我不能把它包括在这里,因为它太大了。如果有人能给我指一些具体的东西,让我在实际计划中看一下,那将非常有帮助
我在一个Spark节点(单机版)上运行它-版本1.6.1。我的代码是用Java编写的。我运行这个的机器有着丰富的处理能力和内存。所以,我很确定这不是问题。非常感谢您的帮助
编辑:我正在使用从CSV文件读取基本数据df1和df2是一些简单的group by+聚合的结果,我认为这不是瓶颈。我有一个类似的问题。到目前为止,我还没有找到一个最佳的方法