带有相关值的最大计数

时间:2017-11-15 07:33:27

标签: java apache-spark

我有一个数据集,其中包含一些颜色和相关日期的计数。

+-----------+----------+-----+
|      color|      Date|count|
+-----------+----------+-----+
|        red|2014-05-26|    5|
|        red|2014-05-02|    1|
|        red|2015-04-02|    1|
|        red|2015-04-26|    1|
|        red|2015-09-26|    2|
|       blue|2014-05-26|    3|
|       blue|2014-06-02|    1|
|      brown|2014-07-31|    2|
|      green|2014-08-01|    2|
+-----------+----------+-----+

我想要每种颜色的最大数量和相关日期。我在Java 8中使用Spark 2.0.2。

当我使用max函数时,它删除了日期列,当我将日期放入groupBy时,它会给出与输入数据集相同的表格。

df.groupBy(color).max("count").show();

+-----------+----------+
|color      |max(count)|
+-----------+----------+
|        red|         5|
|       blue|         3|
|      brown|         2|
|      green|         2|
+-----------+----------+

预期产出:

+-----------+----------+----------+
|color      |      date|max(count)|
+-----------+----------+----------+
|        red|2014-05-26|         5|
|       blue|2014-05-26|         3|
|      brown|2014-07-31|         2|
|      green|2014-08-01|         2|
+-----------+----------+----------+

2 个答案:

答案 0 :(得分:1)

另一个答案部分正确,因为first将返回date上分组生成的群组color的第一个元素。

在问题中,max(count)始终位于该特定颜色的第一个位置,因此声明:

df.groupBy(color).agg(first("date").alias(date),max("count")).show(); 

返回正确的结果。

如果您的数据是这样的:

df.show
// red with highest count is at the bottom of the group
+-----+----------+-----+
|color|      date|count|
+-----+----------+-----+
|  red|2014-05-02|    1|
|  red|2015-04-02|    1|
|  red|2015-04-26|    1|
|  red|2015-09-26|    2|
|  red|2014-05-26|    5|
| blue|2014-05-26|    3|
| blue|2014-06-02|    1|
|brown|2014-07-31|    2|
|green|2014-08-01|    2|
+-----+----------+-----+

有问题的查询将返回组中与计数1对应的第一个日期:

df.groupBy($"color").agg( first($"date").as("date") , max("count").as("count") ).show
+-----+----------+-----+
|color|      date|count|
+-----+----------+-----+
|brown|2014-07-31|    2|
|green|2014-08-01|    2|
| blue|2014-05-26|    3|
|  red|2014-05-02|    5|
+-----+----------+-----+

或者,您可以在此处使用窗口函数:

import org.apache.spark.sql.expression.Window

val window = Window.partitionBy($"color").orderBy($"count".desc)

df.withColumn("rn", row_number over window).where($"rn" === 1 ).drop($"rn").show
+-----+----------+-----+
|color|      date|count|
+-----+----------+-----+
|brown|2014-07-31|    2|
|green|2014-08-01|    2|
| blue|2014-05-26|    3|
|  red|2014-05-26|    5|
+-----+----------+-----+

答案 1 :(得分:-1)

在这里,您需要具有最大值的相关列,以便您可以使用agg()函数获取最大值,并使用first()这些相关列。

df.groupBy(color).agg(first("date").alias(date),max("count")).show();   

+-----------+----------+----------+
|color      |      date|max(count)|
+-----------+----------+----------+
|        red|2014-05-26|         5|
|       blue|2014-05-26|         3|
|      brown|2014-07-31|         2|
|      green|2014-08-01|         2|
+-----------+----------+----------+