Spark Scala Совокупный уникальный счетчик по дате - PullRequest
0 голосов
/ 21 февраля 2019

У меня есть фрейм данных, который дает набор номеров идентификаторов и дату, в которую они посетили определенное место, и я пытаюсь найти способ в scala, чтобы получить количество уникальных людей («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|
+---------------+

IЯ хочу, чтобы выходные данные выглядели так: где я groupBy («дата») и получаю количество уникальных идентификаторов в виде кумулятивного числа.(Так, например: рядом с 2019-01-03 было бы определенное количество идентификаторов в любой день до 2019-01-03)

+----------+-------+
|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 ("дата")

1 Ответ

0 голосов
/ 05 марта 2019

Вам нужно будет использовать функцию 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|
+---+----------+ 

Идентификатор представляет собой идентификатор человека в вашем деле, который может отображаться на нескольких датах.

Вот подсчет на каждую дату.

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

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

Показывает повторное количество идентификаторов для каждой даты.В общей сложности я использовал 3 идентификатора, и каждая дата имеет счет 3, что означает, что все идентификаторы подсчитываются явно в каждую дату.

Теперь, насколько я понимаю, вы хотите, чтобы идентификатор считался только один раз для любой даты (зависит отесли вы хотите самую позднюю дату или самую старую дату).

Я собираюсь использовать самую позднюю дату для каждого идентификатора.

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

Над строкой будут назначаться номера строк для каждого идентификатора для каждой даты против егозапись, а номер строки 1 будет относиться к самой последней дате каждого идентификатора, теперь вы будете считать против каждого идентификатора, где номер строки равен 1. Это приведет к единому счету каждого идентификатора (различного).

ЗдесьНа выходе я применил фильтр к номеру строки, и в выводе вы можете видеть, что даты являются самыми последними, то есть в моем случае 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, что исключает идентификаторы в предыдущие даты, ранее это было 6 (потому что повторение идентификатора в несколько дат)

I чопе он отвечает на ваши вопросы.

...