将宽数据帧转换为长数据帧

时间:2020-08-20 18:29:34

标签: pyspark apache-spark-sql pyspark-dataframes

我有一个数据框,看起来像:

Region, 2000Q1, 2000Q2, 2000Q3, ...
A, 1,2,3,...

我想通过“ Region”将此宽表转换为长表。因此最终产品将如下所示:

Region, Time, Value
A, 2000Q1,1
A, 2000Q2, 2
A, 2000Q3, 3
A, 2000Q4, 4
....

原始表的列非常广泛,但是聚合级别始终是区域,其余列设置为转置。

您知道执行此操作的简单方法或功能吗?

2 个答案:

答案 0 :(得分:1)

先尝试使用 arrays_zip 功能,然后再使用 explode the array

Example:

df=spark.createDataFrame([('A',1,2,3)],['Region','2000q1','2000q2','2000q3'])

from pyspark.sql.functions import *
from pyspark.sql.types import *

df.withColumn("cc",explode(arrays_zip(array(cols),split(lit(col_name),"\\|")))).\
select("Region","cc.*").\
toDF(*['Region','Value','Time']).\
show()
#+------+-----+------+
#|Region|Value|  Time|
#+------+-----+------+
#|     A|    1|2000q1|
#|     A|    2|2000q2|
#|     A|    3|2000q3|
#+------+-----+------+

答案 1 :(得分:0)

与列计算类似,但有所改进。

cols = df.columns
cols.remove('Region')

import pyspark.sql.functions as f

df.withColumn('array', f.explode(f.arrays_zip(f.array(*map(lambda x: f.lit(x), cols)), f.array(*cols), ))) \
  .select('Region', 'array.*') \
  .toDF('Region', 'Time', 'Value') \
  .show(30, False)

+------+------+-----+
|Region|Time  |Value|
+------+------+-----+
|A     |2000Q1|1    |
|A     |2000Q2|2    |
|A     |2000Q3|3    |
|A     |2000Q4|4    |
|A     |2000Q5|5    |
+------+------+-----+

p.s。不要接受这个作为答案:)