Spark Scala按日期累计唯一计数

时间:2019-02-21 17:17:49

标签: scala date apache-spark grouping cumulative-sum

我有一个数据框,该数据框提供一组ID号以及他们访问特定位置的日期,我正在尝试在Spark Scala中找到一种方法来获取具有以下ID的唯一身份人员(“ ID”)的数量:每天或之前访问此位置,例如,如果一个ID号在2019-01-01到2019-01-07再次访问,则不会被计算两次。

df.show(5,false)

+---------------+
|id  |date      |
+---------------+
|3424|2019-01-02|
|8683|2019-01-01|
|7690|2019-01-02|
|3424|2019-01-07|
|9002|2019-01-02|
+---------------+

我希望输出看起来像这样:在哪里我groupBy(“ date”)并获得唯一ID的计数作为累积数字。 (因此,例如:在2019年1月3日旁边,它将提供截至2019年1月3日的任意一天的ID的唯一计数)

+----------+-------+
|date      |cum_ct |
+----------+-------+
|2019-01-01|xxxxx  |
|2019-01-02|xxxxx  |
|2019-01-03|xxxxx  |
|...       |...    |
|2019-01-08|xxxxx  |
|2019-01-09|xxxxx  |
+------------------+

在df.groupBy(“ date”)之后执行此操作的最佳方法是什么?

1 个答案:

答案 0 :(得分:0)

在这种情况下,您将必须使用ROW_NUMBER()函数。我已经创建了一个数据框

val df = Seq((1,"2019-05-03"),(1,"2018-05-03"),(2,"2019-05-03"),(2,"2018-05-03"),(3,"2019-05-03"),(3,"2018-05-03")).toDF("id","date")

df.show

+---+----------+
| id|      date|
+---+----------+
|  1|2019-05-03|
|  1|2018-05-03|
|  2|2019-05-03|
|  2|2018-05-03|
|  3|2019-05-03|
|  3|2018-05-03|
+---+----------+ 

ID代表您的情况下的人员ID,可以针对多个日期显示。

这是每个日期的计数。

df.groupBy("date").count.show

+----------+-----+
|      date|count|
+----------+-----+
|2018-05-03|    3|
|2019-05-03|    3|
+----------+-----+

这显示了每个日期对ID的重复计数。我总共使用了3个id,每个日期都有3个计数,这意味着所有id在每个日期中都被明确计数。

据我所知,您希望对任何日期仅对ID进行一次计数(取决于您是希望最新日期还是最早的日期)。

我将为每个ID使用最新日期。

val newdf = df.withColumn("row_num",row_number().over(Window.partitionBy($"id").orderBy($"date".desc)))

以上一行将针对每个ID为其输入的每个日期分配行号,并且行号1表示每个ID的最新日期,现在您对行号为1的每个ID进行计数。每个ID的唯一计数(不重复)。

这里是输出,我对行号应用了过滤器,您可以在输出中看到日期是最新的,即我的情况是2019年。

newdf.select("id","date","row_num").where("row_num = 1").show()

+---+----------+-------+
| id|      date|row_num|
+---+----------+-------+
|  1|2019-05-03|      1|
|  3|2019-05-03|      1|
|  2|2019-05-03|      1|
+---+----------+-------+

现在,我将使用具有相同过滤器的NEWDF进行计数,该过滤器将返回按日期进行计数。

newdf.groupBy("date","row_num").count().filter("row_num = 1").select("date","count").show

+----------+-----+
|      date|count|
+----------+-----+
|2019-05-03|    3|
+----------+-----+

这里的总数为3,其中不包括先前日期的ID,之前为6(因为ID在多个日期重复)

希望它能回答您的问题。