#apache-spark #pyspark #apache-spark-sql
Вопрос:
У меня есть главный стол, как
----------- ---------- ------------- | Age | Gender | date | ----------- ---------- ------------- | [1,2] | M | 2021-01-01 | | [11,13] | M | 2021-01-10 | | [4,5] | M | 2021-01-15 | | [3] | M | 2021-01-30 | | [7] | F | 2021-02-01 | | [2] | F | 2021-02-16 | | [6] | F | 2021-02-20 |
Требуемая мощность составляет Я взял карту на 15 дней, но возрастную карту даты можно изменить на 15,30,45 дней и т. Д
----------- ---------- ----------------------------------------------------------- | Age | Gender | date_age_map | ----------- ---------- ----------------------------------------------------------- | [1,2] | M | [2021-01-01--gt;[1,2]] | | [11,13] | M | [[2021-01-01--gt;[1,2]],[2021-01-10--gt;[11,13]]] | | [4,5] | M | [[2021-01-01--gt;[1,2]],[2021-01-10--gt;[11,13]],[2021-01-15--gt;[4,5]]] | | [3] | M | [2021-01-30--gt;[3]] | | [7] | F | [2021-02-01--gt;[7]] | | [2] | F | [[2021-02-01--gt;[7]],[2021-02-16--gt;[2]]] | | [6] | F | [2021-02-20--gt;[6]] |
Я приложил некоторые усилия, как показано ниже
spark.sql(""" select Age,Gender,collect_list(date_age_map) over (partition by gender order by date) as date_age_map from select Age,Gender,map(date,age) as date_age_map from master""")
есть ли какой-либо способ сделать это с помощью оконных функций с помощью spark df,spark sql или UDF
Комментарии:
1. можете ли вы объяснить, почему 4-я строка (Возраст = [3]) содержит только один элемент
date_age_map
?2. карта возраста и даты требуется для 15 дней.. с даты 2021-01-01 по 2021-01-16 будут в одной группе, а записи с 2021-01-17 по 2021-01-31 будут следующей группой, так как других дат с 2021-01-17 по 31-ю строку 4-я содержит только один элемент
3. как насчет даты 2021-01-21 ? Группируется ли он с 2021-01-15?
4. вероятно, вам следует ответить на мой вопрос, потому что в зависимости от этого ответ от blackbishop может быть неправильным.
Ответ №1:
Вы можете использовать окно с rangeBetween
, чтобы исправить интервал скольжения окна при сборе age
и date
значений для создания вашей карты.
Что-то вроде этого:
from pyspark.sql import Window import pyspark.sql.functions as F days = 15 # define a window with range between interval 15 days preceding and current row # 86400 is the number of second in one day w = Window.partitionBy("gender").orderBy("date2").rangeBetween(-days * 86400, 0) df1 = df.withColumn( "date2", F.col("date").cast("timestamp").cast("long") ).withColumn( "date_age_map", F.map_from_arrays( F.collect_list("date").over(w), F.collect_list("age").over(w) ) ).drop("date2") df1.show(truncate=False) # -------- ------ ---------- -------------------------------------------------------------------- #|age |gender|date |date_age_map | # -------- ------ ---------- -------------------------------------------------------------------- #|[7] |F |2021-02-01|[2021-02-01 -gt; [7]] | #|[2] |F |2021-02-16|[2021-02-01 -gt; [7], 2021-02-16 -gt; [2]] | #|[6] |F |2021-02-20|[2021-02-16 -gt; [2], 2021-02-20 -gt; [6]] | #|[1, 2] |M |2021-01-01|[2021-01-01 -gt; [1, 2]] | #|[11, 13]|M |2021-01-10|[2021-01-01 -gt; [1, 2], 2021-01-10 -gt; [11, 13]] | #|[4, 5] |M |2021-01-15|[2021-01-01 -gt; [1, 2], 2021-01-10 -gt; [11, 13], 2021-01-15 -gt; [4, 5]]| #|[3] |M |2021-01-30|[2021-01-15 -gt; [4, 5], 2021-01-30 -gt; [3]] | # -------- ------ ---------- --------------------------------------------------------------------