Pyspark Group и порядок по сумме для группы делятся на части - PullRequest
2 голосов
/ 14 апреля 2020

Я новичок в pyspark и запутался в том, как сгруппировать некоторые данные по нескольким столбцам, упорядочить их по другому столбцу, затем добавить столбец для каждой из групп, а затем использовать его в качестве знаменателя для каждой строки данных для расчета веса в каждой строке, составляющей группы.

Это делается в jupyterlab с использованием блокнота pyspark3. Обойти это невозможно.

Вот пример данных ...

+-------+-----+-----------+------------+------+--------+
| ntwrk | zip | zip-ntwrk | event-date | hour | counts |
+-------+-----+-----------+------------+------+--------+
| A     | 1   | 1-A       | 2019-10-10 | 1    | 12362  |
| B     | 3   | 3-B       | 2019-10-10 | 1    | 100    |
| C     | 5   | 5-C       | 2019-10-10 | 1    | 17493  |
| B     | 3   | 3-B       | 2019-10-10 | 4    | 4873   |
| A     | 2   | 2-A       | 2019-10-11 | 1    | 28730  |
| C     | 6   | 6-C       | 2019-10-11 | 1    | 728    |
| C     | 5   | 5-C       | 2019-10-10 | 2    | 9827   |
| A     | 1   | 1-A       | 2019-10-10 | 9    | 13245  |
| B     | 4   | 4-B       | 2019-10-11 | 1    | 3765   |
+-------+-----+-----------+------------+------+--------+

Я бы хотел сгруппировать их по ntrk, zipcode, zip-ntwrk, событие-дата, а затем упорядочить его по дате события des c и часу des c. Для каждой даты есть 24 часа, поэтому для каждого комбо zip-ntwrk я бы хотел видеть дату и час по порядку. Примерно так ...

+-------+-----+-----------+------------+------+--------+
| ntwrk | zip | zip-ntwrk | event-date | hour | counts |
+-------+-----+-----------+------------+------+--------+
| A     | 1   | 1-A       | 2019-10-10 | 1    | 12362  |
| A     | 1   | 1-A       | 2019-10-10 | 9    | 3765   |
| A     | 2   | 2-A       | 2019-10-11 | 1    | 28730  |
| B     | 3   | 3-B       | 2019-10-10 | 1    | 100    |
| B     | 3   | 3-B       | 2019-10-10 | 4    | 4873   |
| B     | 4   | 4-B       | 2019-10-11 | 1    | 3765   |
| C     | 5   | 5-C       | 2019-10-10 | 1    | 17493  |
| C     | 5   | 5-C       | 2019-10-10 | 2    | 9827   |
| C     | 6   | 6-C       | 2019-10-11 | 1    | 728    |
+-------+-----+-----------+------------+------+--------+

Теперь, когда все в порядке, мне нужно выполнить расчет, чтобы создать соотношение количества подсчетов за каждый час по сравнению с суммой подсчетов за каждый день. при объединении часов. Это будет использоваться в знаменателе для деления почасового подсчета на общее количество, чтобы получить отношение количества подсчетов за каждый час к общему количеству за день. Итак, что-то вроде этого ...

+-------+-----+-----------+------------+------+--------+-------+
| ntwrk | zip | zip-ntwrk | event-date | hour | counts | total |
+-------+-----+-----------+------------+------+--------+-------+
| A     | 1   | 1-A       | 2019-10-10 | 1    | 12362  | 16127 |
| A     | 1   | 1-A       | 2019-10-10 | 9    | 3765   | 16127 |
| A     | 2   | 2-A       | 2019-10-11 | 1    | 28730  | 28730 |
| B     | 3   | 3-B       | 2019-10-10 | 1    | 100    | 4973  |
| B     | 3   | 3-B       | 2019-10-10 | 4    | 4873   | 4973  |
| B     | 4   | 4-B       | 2019-10-11 | 1    | 3765   | 3765  |
| C     | 5   | 5-C       | 2019-10-10 | 1    | 17493  | 27320 |
| C     | 5   | 5-C       | 2019-10-10 | 2    | 9827   | 27320 |
| C     | 6   | 6-C       | 2019-10-11 | 1    | 728    | 728   |
+-------+-----+-----------+------------+------+--------+-------+

И теперь, когда у нас есть знаменатель, мы можем разделить счетчики на сумму для каждой строки, чтобы получить коэффициент count / total = factor, и в итоге это выглядело бы так. ..

+-------+-----+-----------+------------+------+--------+-------+--------+
| ntwrk | zip | zip-ntwrk | event-date | hour | counts | total | factor |
+-------+-----+-----------+------------+------+--------+-------+--------+
| A     | 1   | 1-A       | 2019-10-10 | 1    | 12362  | 16127 | .766   |
| A     | 1   | 1-A       | 2019-10-10 | 9    | 3765   | 16127 | .233   |
| A     | 2   | 2-A       | 2019-10-11 | 1    | 28730  | 28730 | 1      |
| B     | 3   | 3-B       | 2019-10-10 | 1    | 100    | 4973  | .02    |
| B     | 3   | 3-B       | 2019-10-10 | 4    | 4873   | 4973  | .979   |
| B     | 4   | 4-B       | 2019-10-11 | 1    | 3765   | 3765  | 1      |
| C     | 5   | 5-C       | 2019-10-10 | 1    | 17493  | 27320 | .64    |
| C     | 5   | 5-C       | 2019-10-10 | 2    | 9827   | 27320 | .359   |
| C     | 6   | 6-C       | 2019-10-11 | 1    | 728    | 728   | 1      |
+-------+-----+-----------+------------+------+--------+-------+--------+

Это то, что я пытаюсь сделать, и любые советы о том, как это сделать, будут с благодарностью.

Спасибо

Ответы [ 3 ]

2 голосов
/ 14 апреля 2020

Используйте window sum функцию, а затем sum над разделом окна на ntwrk,zip.

  • наконец мы разделим на counts/total.

Example:

from pyspark.sql.functions import *
from pyspark.sql import Window
w = Window.partitionBy("ntwrk","zip","event-date")

df1.withColumn("total",sum(col("counts")).over(w).cast("int")).orderBy("ntwrk","zip","event-date","hour").\
withColumn("factor",format_number(col("counts")/col("total"),3)).show()

#+-----+---+---------+----------+----+------+-----+------+
#|ntwrk|zip|zip-ntwrk|event-date|hour|counts|total|factor|
#+-----+---+---------+----------+----+------+-----+------+
#|    A|  1|      1-A|2019-10-10|   1| 12362|25607| 0.483|
#|    A|  1|      1-A|2019-10-10|   9| 13245|25607| 0.517|#input 13245 not 3765
#|    A|  2|      2-A|2019-10-11|   1| 28730|28730| 1.000|
#|    B|  3|      3-B|2019-10-10|   1|   100| 4973| 0.020|
#|    B|  3|      3-B|2019-10-10|   4|  4873| 4973| 0.980|
#|    B|  4|      4-B|2019-10-11|   1|  3765| 3765| 1.000|
#|    C|  5|      5-C|2019-10-10|   1| 17493|27320| 0.640|
#|    C|  5|      5-C|2019-10-10|   2|  9827|27320| 0.360|
#|    C|  6|      6-C|2019-10-11|   1|   728|  728| 1.000|
#+-----+---+---------+----------+----+------+-----+------+
1 голос
/ 23 апреля 2020

Вы, должно быть, сетчатые сплайны

0 голосов
/ 23 апреля 2020

Pyspark работает над распределительной архитектурой и, следовательно, может не сохранять порядок. Таким образом, вы всегда должны упорядочить его так, как вам нужно, прежде чем показывать записи.

Теперь, на вашей точке, чтобы получить% записей на разных уровнях. Вы можете добиться того же, используя оконную функцию, разделив ее на уровни, которые вы хотите получить.

Например: w = Window.partitionBy ("ntwrk-zip", "hour") df = df.withColumn (" hourly_recs ", F.count (). over (w))

Также вы можете обратиться к этому руководству в YouTube - https://youtu.be/JEBd_4wWyj0

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...