在Spark 1.6 / Scala中,使列值与聚合相关联

时间:2017-05-19 22:52:00

标签: scala apache-spark dataframe spark-dataframe

我们说我有一个包含三列的DataFrame:

itemid, date, price
1, 2017-05-18, $1.10
2, 2017-05-18, $2.20
1, 2017-04-12, $0.90
1, 2017-03-29, $1.00

现在,我想按itemid分组,获取最早的日期,并获得与最早日期相匹配的价格。 (我们可以假设(itemid,date)是唯一的。)

上面输入的输出为:

1, 2017-03-29, $1.00
2, 2017-05-18, $2.20

在SQL中,我可以使用自联接来执行此操作 - 首先选择每个itemid的最小日期,然后选择日期与最小日期匹配的价格和日期。

如何在Scala Spark DataFrames中表达这一点? 如果答案仍然涉及自联接,那么Spark 1.6中的DataFrame查询执行器是否足够智能,实际上不会实现连接?

1 个答案:

答案 0 :(得分:1)

一种方法是使用类似于以下内容的SparkSQL窗口函数:

import org.apache.spark.sql.expressions.Window

val df = Seq(
    (1, "2017-05-18", 1.10),
    (2, "2017-05-18", 2.20),
    (1, "2017-04-12", 0.90),
    (1, "2017-03-29", 1.00)
  ).toDF(
    "itemid", "date", "price"
  ).as[(Integer, String, Double)]

// Add earliest date by itemid via window function and
// keep only rows with earliest date by itemid
val df2 = df.withColumn("earliestDate", min("date").over(
    Window.partitionBy("itemid")
  )).
  where($"date" === $"earliestDate")

df2.show
+------+----------+-----+------------+
|itemid|      date|price|earliestDate|
+------+----------+-----+------------+
|     1|2017-03-29|  1.0|  2017-03-29|
|     2|2017-05-18|  2.2|  2017-05-18|
+------+----------+-----+------------+