【问题标题】:pyspark - Convert column string to header and valuespyspark - 将列字符串转换为标题和值
【发布时间】:2021-04-12 16:39:06
【问题描述】:
我有一个带有四列字符串的 pyspark.sql.dataframe.DataFrame,例如:
| id |
col1 |
col2 |
col3 |
| z10234 |
Header One : teacher |
Header Two : salary |
Header Three : 12 |
| z10235 |
Header One : plumber |
Header Two : hourly |
Header Three : 15 |
| z10236 |
Header One : executive |
Header Two : salary |
Header Three : 17 |
| z10237 |
Header One : teacher |
Header Two : salary |
Header Three : 15 |
| z10238 |
Header One : manager |
Header Two : hourly |
Header Three : 11 |
我需要转换每个字符串 col1、col2 和 col3,使字符串的初始部分成为标题:
| id |
HeaderOne |
HeaderTwo |
HeaderThree |
| z10234 |
teacher |
salary |
12 |
| z10235 |
plumber |
hourly |
15 |
| z10236 |
executive |
salary |
17 |
| z10237 |
teacher |
salary |
15 |
| z10238 |
manager |
hourly |
11 |
【问题讨论】:
标签:
apache-spark
pyspark
apache-spark-sql
【解决方案1】:
您可以用冒号拆分,将第一部分作为列名,将第二部分作为列值:
import pyspark.sql.functions as F
names = df.limit(1).select(
[F.split(c, ' : ')[0].alias(c) for c in df.columns[1:]]
).head().asDict()
df2 = df.select(
'id',
*[F.split(c, ' : ')[1].alias(names[c]) for c in df.columns[1:]]
)
df2.show()
+------+----------+----------+------------+
| id|Header One|Header Two|Header Three|
+------+----------+----------+------------+
|z10234| teacher| salary| 12|
|z10235| plumber| hourly| 15|
|z10236| executive| salary| 17|
|z10237| teacher| salary| 15|
|z10238| manager| hourly| 11|
+------+----------+----------+------------+
【解决方案2】:
另一种方法是为每一列创建MapType,然后按groupby+pivot 展开:
from pyspark.sql import functions as F
columns = ['col1','col2','col3']
def fun(c):
c1 = F.split(c,":")
return F.create_map(c1[0],c1[1]) #Since there can only be 2 strings
out = (df.select("id",*[fun(x).alias(x) for x in columns])
.select("id",F.explode(F.map_concat(*columns)))
.groupby("id").pivot("Key").agg(F.first("value")))
out.show()
+------+-----------+-------------+-----------+
| id|Header One |Header Three |Header Two |
+------+-----------+-------------+-----------+
|z10234| teacher| 12| salary|
|z10235| plumber| 15| hourly|
|z10236| executive| 17| salary|
|z10237| teacher| 15| salary|
|z10238| manager| 11| hourly|
+------+-----------+-------------+-----------+