Квартальные различия

#python #apache-spark #pyspark #apache-spark-sql

#python #apache-spark #pyspark #apache-spark-sql

Вопрос:

У меня есть простой фрейм данных Spark, в котором хранятся квартальные итоги с начала 2020 года.

 |  id | year | quarter |   yq   |  total |
|:---:|:----:|:-------:|:------:|:------:|
| 1   | 2020 | 1       | 202001 | 23     |
| 1   | 2020 | 2       | 202002 | 3545   |
| 1   | 2020 | 3       | 202003 | 3      |
| 1   | 2020 | 4       | 202004 | 5345   |
| 1   | 2021 | 1       | 202101 | 3534   |
| 2   | 2020 | 1       | 202001 | 567    |
| 2   | 2020 | 2       | 202002 | 35     |
| 2   | 2020 | 3       | 202003 | 989    |
| 2   | 2020 | 4       | 202004 | 78786  |
| 2   | 2021 | 1       | 202101 | 321    |
| ... | ..   | ...     | ...    | ...    |
 

Как я могу сравнить разницу в% между текущим кварталом и тем же кварталом предыдущего года?

Ожидаемый результат:

 | id  | yq     | growth_over_same_quarter_in_previous_year |
|-----|--------|-------------------------------------------|
| 1   | 202101 | 197                                       |
| 2   | 202101 | -55                                       |
| ... | ...    | ...                                       |
 

Ответ №1:

Вы можете использовать lag для сравнения с предыдущим кварталом того же года для того же идентификатора.

 from pyspark.sql import functions as F, Window

last_year = F.lag('total').over(Window.partitionBy('id', 'quarter').orderBy('year'))

df2 = df.withColumn(
    'change',
    (F.col('total') - last_year) / last_year * 100
).filter('change is not null').select('id', 'yq', 'change')

df2.show()
 --- ------ ------------------- 
| id|    yq|             change|
 --- ------ ------------------- 
|  1|202101| 15265.217391304346|
|  2|202101|-43.386243386243386|
 --- ------ ------------------- 
 

Комментарии:

1. Какова цель фильтра здесь? Чтобы учесть 0 изменений?

2. Для случая, если предыдущей строки нет (например, yq = 202001), where lag вернет null, и поэтому change также будет null @Someguywhocodes