如何在JAVA中加入没有重复列的Spark数据框

Posted

技术标签:

【中文标题】如何在JAVA中加入没有重复列的Spark数据框【英文标题】:How to join Spark dataframe without duplicate columns in JAVA 【发布时间】:2017-02-09 11:58:12 【问题描述】:

我们如何合并 2 个没有重复列的数据框

a.show()

+-----+-------------------+--------+------+
| Name|           LastTime|Duration|Status|
+-----+-------------------+--------+------+
|  Bob|2015-04-23 12:33:00|       1|logout|
|Alice|2015-04-20 12:33:00|       5| login|
+-----+-------------------+--------+------+

b.show()
+-----+-------------------+--------+------+
| Name|           LastTime|Duration|Status|
+-----+-------------------+--------+------+
|  Bob|2015-04-24 00:33:00|       1|login |
+-----+-------------------+--------+------+

我想通过使用数据框 A 中的整个数据来形成一个新的数据框,但使用 B 中的数据更新行

+-----+-------------------+--------+------+
| Name|           LastTime|Duration|Status|
+-----+-------------------+--------+------+
|  Bob|2015-04-24 00:33:00|       1|login |
|Alice|2015-04-20 12:33:00|       5| login|
+-----+-------------------+--------+------+

我能够在 scala 中加入和形成数据框。但不能在JAVA中做。

DataFrame f=a.join(b,a.col("Name").equalsTo(b.col("Name")).and a.col("LastTime).equalsTo(b.col("LastTime).and(a.col("Duration").equalsTo(b.col("Duration"),"outer")

我在像这样执行 JOIN 时得到重复的列。

【问题讨论】:

【参考方案1】:

根据this SO answer 的列名序列在Scala 中解决了这个问题。

Hance,converting a Java List to Scala Seq 应该这样做,或者你。这是您更正后的示例代码:

DataFrame f = a.join(b,
    // Convert Java List to Scala Seq
    scala.collection.JavaConverters.asScalaIteratorConverter(
        Arrays.asList("Name", "LastTime", "Duration").iterator()
    ).asScala().toSeq(),
    "outer"
)

【讨论】:

【参考方案2】:

正确的方法是:(已测试)

Dataset<Row> f = a.join(b,
// Convert Java List to Scala Seq
JavaConverters.collectionAsScalaIterableConverter(
    Arrays.asList("Name", "LastTime", "Duration"))
.asScala().toSeq(),
"outer"
)

【讨论】:

【参考方案3】:

我觉得我们可以通过Spark SQL试试,也可以通过java来执行。

spark.sql("""SELECT a.Name as Name,
CASE WHEN b.Name is null THEN a.LastTime ELSE b.LastTime END AS LastTime,
CASE WHEN b.Name is null THEN a.Duration ELSE b.Duration END AS Duration,
CASE WHEN b.Name is null THEN a.Status ELSE b.Status END AS Status 
FROM a a left outer join  b b on a.Name=b.Name 
""").show(false)

+-----+-------------------+--------+------+
|Name |LastTime           |Duration|Status|
+-----+-------------------+--------+------+
|Bob  |2015-04-24 00:33:00|1       |login |
|Alice|2015-04-20 12:33:00|5       |login |
+-----+-------------------+--------+------+

可以根据用例更新连接条件

【讨论】:

【参考方案4】:

您可以执行左半联接(“leftsemi”)以避免 b 数据集中的重复列。

参考这里:http://www.techburps.com/misc/apache-spark-dataset-joins-in-java/129

【讨论】:

以上是关于如何在JAVA中加入没有重复列的Spark数据框的主要内容,如果未能解决你的问题,请参考以下文章

在 Spark 中加入多个表的有效方法 - 设备上没有剩余空间

在 Spark Java API 中加入行数据集

有没有办法限制在 spark sql 中加入表时读取的数据?

在 Spark 中加入倾斜的数据集?

在 Spark 中加入数据集

在 Spark 中加入数据框