【问题标题】:Spark Scala Cumulative Unique Count by DateSpark Scala 累积唯一计数(按日期)
【发布时间】:2019-07-15 16:51:49
【问题描述】:

我有一个数据框,它提供了一组 id 编号和他们访问某个位置的日期,我试图在 spark scala 中找到一种方法来获取拥有的唯一人员(“id”)的数量每天或之前访问过此位置,这样如果他们在 2019 年 1 月 1 日访问,然后在 2019 年 1 月 7 日再次访问,则不会将一个 ID 号计算两次。

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-01-03 旁边,它将在 2019-01-03 之前的任何一天给出不同的 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") 之后最好的方法是什么

【问题讨论】:

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


    【解决方案1】:

    在这种情况下,您必须使用 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)

    我希望它能回答你的问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-01-26
      • 1970-01-01
      • 2014-01-03
      • 2013-03-19
      • 2021-06-09
      • 1970-01-01
      • 1970-01-01
      • 2022-08-22
      相关资源
      最近更新 更多