#python #sql #dataframe #pyspark #apache-spark-sql
#python #sql #фрейм данных #pyspark #apache-spark-sql
Вопрос:
Как транспонировать следующий фрейм данных PySpark?
Ниже приведен фрейм данных PySpark.
---- ------ ----- ----- ----- ----- ----- ----- ----- ----- ----- ---------------- -------- ------
|srab|srsbtp|avgm1|avgm2|avgm3|avgm4|avgm4|avgm6|avgm7|avgm8|avgm9| avgm10| avgm11|avgm12|
---- ------ ----- ----- ----- ----- ----- ----- ----- ----- ----- ---------------- -------- ------
|2389| D| null| null| null| null| null| null| null| null| null| null| null| null|
|2389| C| null| null| null| null| null| null| null| null| null|54674.1935483871|156820.0| null|
---- ------ ----- ----- ----- ----- ----- ----- ----- ----- ----- ---------------- -------- ------
Я хочу преобразовать приведенный выше фрейм данных в следующую таблицу
Желаемый результат:
srab month D C
2389 avgm1 null null
2389 avgm2 null null
2389 avgm3 null null
2389 avgm4 null null
2389 avgm5 null null
2389 avgm6 null null
2389 avgm7 null null
2389 avgm8 null null
2389 avgm9 null null
2389 avgm10 null 54674.19355
2389 avgm11 null 156820
2389 avgm12 null null
Ответ №1:
В Spark SQL вы можете отключить / преобразовать с union all
помощью и условной агрегации:
select srab, month,
max(case when srsbtp = 'D' then avgm1 end) as d,
max(case when srsbtp = 'C' then avgm1 end) as c
from (
select srab, srsbtp, 'avgm1' as month, avgm1 from mytable
union all srab, srsbtp, 'avgm2', avgm2 from mytable
union all srab, srsbtp, 'avgm3', avgm3 from mytable
...
) t
gorup by srab, month
Ответ №2:
Сначала мы можем преобразовать stack
avgm
столбцы в строки, затем pivot
srsbtp
строки в столбцы.
df.createOrReplaceTempView('table')
col_list = ' '.join([f"'{'avgm' str(i 1)}', {'avgm' str(i 1)}," for i in range(12)])[:-1]
## col_list is a string
## "'avgm1', avgm1, 'avgm2', avgm2, 'avgm3', avgm3, 'avgm4', avgm4, 'avgm5', avgm5, 'avgm6', avgm6, 'avgm7', avgm7, 'avgm8', avgm8, 'avgm9', avgm9, 'avgm10', avgm10, 'avgm11', avgm11, 'avgm12', avgm12"
result = spark.sql(f"select srab, srsbtp, stack(12, {col_list}) as (month, value) from table")
.groupBy('srab', 'month')
.pivot('srsbtp')
.agg(F.sum('value'))
.orderBy('month')
result.show()
---- ------ ---------------- ----
|srab| month| C| D|
---- ------ ---------------- ----
|2389| avgm1| null|null|
|2389|avgm10|54674.1935483871|null|
|2389|avgm11| 156820.0|null|
|2389|avgm12| null|null|
|2389| avgm2| null|null|
|2389| avgm3| null|null|
|2389| avgm4| null|null|
|2389| avgm5| null|null|
|2389| avgm6| null|null|
|2389| avgm7| null|null|
|2389| avgm8| null|null|
|2389| avgm9| null|null|
---- ------ ---------------- ----