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

时间:2017-02-09 11:58:13

标签: java apache-spark apache-spark-sql spark-dataframe

如何在没有重复列的情况下合并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 |
+-----+-------------------+--------+------+

我想通过使用Dataframe 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时会收到重复的列。

4 个答案:

答案 0 :(得分:1)

正确的方法是:(经过测试)

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

答案 1 :(得分:1)

我认为我们可以通过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 |
+-----+-------------------+--------+------+

一个人可以根据用例更新联接条件

答案 2 :(得分:0)

根据this SO answer,Seq的列名称在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"
)

答案 3 :(得分:0)

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

请参阅此处以供参考:http://www.techburps.com/misc/apache-spark-dataset-joins-in-java/129