#python #apache-spark #pyspark #apache-spark-sql
#python #apache-spark #pyspark #apache-spark-sql
Вопрос:
У меня есть некоторые ежедневные данные, хранящиеся в Spark dataframe, которые я агрегирую, чтобы получить количество. Я делаю это так:
start = '2018-11-01'
end = '2021-02-19'
t1 = (
spark.table('schema.t1')
.where(sf.col('yyyy_mm_dd').between(start, end))
.select('yyyy_mm_dd', 'x_id', 'h_id', 'app', 'kpi')
)
Затем я объединяю и объединяю со вторым фреймом данных, который содержит список продуктов.
aggregate = (
t1
.join(t2, on = ['app', 'kpi'], how = 'left')
.groupby('x_id', 'product')
.agg(
sf.countDistinct('h_id').alias('count_ever')
)
)
Приведенная выше агрегация позволяет мне видеть отчетливое количество h_id
использованных каждого продукта с тех пор 2018-11-01
, за x_id
.
Мне было интересно, как я могу изменить агрегацию, чтобы она все еще выполнялась countDistinct()
, но между датами начала и окончания квартала, а не за все время.
Поэтому вместо подсчета ever ( 2018-11-01 -> 2021-02-19
), как это делает мой код, я бы посчитал эти диапазоны:
2018-11-01 -> 2018-12-31
2019-01-01 -> 2019-03-31
2019-04-01 -> 2019-06-30
2019-07-01 -> 2019-09-30
2019-10-01 -> 2019-12-31
2020-01-01 -> 2020-03-31
2020-04-01 -> 2020-06-30
2020-07-01 -> 2020-09-30
2020-10-01 -> 2020-12-31
2021-01-01 -> 2021-02-19
Ожидаемый результат будет таким же, как и в моем коде, но с дополнительной группировкой по годам / кварталам.
Ответ №1:
Вы также можете сгруппировать по кварталу, используя trunc
по дате:
aggregate = (
t1
.join(t2, on = ['app', 'kpi'], how = 'left')
.groupby('x_id', 'product', sf.trunc(sf.to_date('yyyy_mm_dd', 'yyyy_MM_dd'), 'quarter').alias('quarter'))
.agg(
sf.countDistinct('h_id').alias('count_ever')
)
)
Комментарии:
1. Я думаю, что это группируется только по кварталам, а не по годам и кварталам, но я попробую!
2. @Someguywhocodes группирует как по году, так и по кварталу. Результат
trunc
будет примерно таким, как2021-01-01
на сегодняшний день.3. Столбец quarter возвращает для меня значение null. Возможно, это проблема с моей стороны, так что я рассмотрю ее подробнее. Я использую Spark 2.2.0, если это имеет значение
4. @Someguywhocodes столбец yyyy_mm_dd должен быть в стандартной форме (гггг-мм-дд). Это относится к вашим реальным данным?
5. @Someguywhocodes затем вам нужно сначала преобразовать этот столбец в тип даты, используя
to_date
. Смотрите мой отредактированный ответ.