将多列分解为pyspark中的行
Explode multiple columns to rows in pyspark
我有以下 spark 数据框。
Name age subject parts
xxxx 21 Maths,Physics I
yyyy 22 English,French I,II
我正在尝试在主题和部分中分解上述数据框,如下所示。
预期输出:
Name age subject parts
xxxx 21 Maths I
xxxx 21 Physics I
yyyy 22 English I
yyyy 22 English II
yyyy 22 French I
yyyy 22 French II
我尝试对主题和部分使用 array.zip,然后尝试使用临时列展开,但我在只有一个部分的地方得到了空值。
有没有办法在 Pyspark 中实现这个。
您可以将它们分开,然后将它们重新组合在一起[=13=]
拆分科目
df1 = (df
.select('name', 'age', 'subject')
.withColumn('subject', F.explode(F.split('subject', ',')))
)
# +----+---+-------+
# |name|age|subject|
# +----+---+-------+
# |xxxx| 21| Maths|
# |xxxx| 21|Physics|
# |yyyy| 22|English|
# |yyyy| 22| French|
# +----+---+-------+
拆分部分
df2 = (df
.select('name', 'age', 'parts')
.withColumn('parts', F.explode(F.split('parts', ',')))
)
# +----+---+-----+
# |name|age|parts|
# +----+---+-----+
# |xxxx| 21| I|
# |yyyy| 22| I|
# |yyyy| 22| II|
# +----+---+-----+
重新加入
df1.join(df2, on=['name', 'age'])
# +----+---+-------+-----+
# |name|age|subject|parts|
# +----+---+-------+-----+
# |xxxx| 21| Maths| I|
# |xxxx| 21|Physics| I|
# |yyyy| 22|English| I|
# |yyyy| 22|English| II|
# |yyyy| 22| French| I|
# |yyyy| 22| French| II|
# +----+---+-------+-----+
我通过将列作为列表传递给 for 循环并分解列表中每个元素的数据框来做到这一点
数据样本
df.show()
+----+---+--------------+-----+
|Name|age| subject|parts|
+----+---+--------------+-----+
|xxxx| 21| Maths,Physics| I|
|yyyy| 22|English,French| I,II|
+----+---+--------------+-----+
df.printSchema()
root
|-- Name: string (nullable = true)
|-- age: long (nullable = true)
|-- subject: string (nullable = true)
|-- parts: string (nullable = true)
数据转换
from pyspark.sql import functions as F
df.withColumn(
"subject", F.explode(F.split("subject", ","))
).withColumn(
"parts", F.explode(F.split("parts", ","))
).show()
+----+---+-------+-----+
|Name|age|subject|parts|
+----+---+-------+-----+
|xxxx| 21| Maths| I|
|xxxx| 21|Physics| I|
|yyyy| 22|English| I|
|yyyy| 22|English| II|
|yyyy| 22| French| I|
|yyyy| 22| French| II|
+----+---+-------+-----+
我有以下 spark 数据框。
Name age subject parts
xxxx 21 Maths,Physics I
yyyy 22 English,French I,II
我正在尝试在主题和部分中分解上述数据框,如下所示。
预期输出:
Name age subject parts
xxxx 21 Maths I
xxxx 21 Physics I
yyyy 22 English I
yyyy 22 English II
yyyy 22 French I
yyyy 22 French II
我尝试对主题和部分使用 array.zip,然后尝试使用临时列展开,但我在只有一个部分的地方得到了空值。
有没有办法在 Pyspark 中实现这个。
您可以将它们分开,然后将它们重新组合在一起[=13=]
拆分科目
df1 = (df
.select('name', 'age', 'subject')
.withColumn('subject', F.explode(F.split('subject', ',')))
)
# +----+---+-------+
# |name|age|subject|
# +----+---+-------+
# |xxxx| 21| Maths|
# |xxxx| 21|Physics|
# |yyyy| 22|English|
# |yyyy| 22| French|
# +----+---+-------+
拆分部分
df2 = (df
.select('name', 'age', 'parts')
.withColumn('parts', F.explode(F.split('parts', ',')))
)
# +----+---+-----+
# |name|age|parts|
# +----+---+-----+
# |xxxx| 21| I|
# |yyyy| 22| I|
# |yyyy| 22| II|
# +----+---+-----+
重新加入
df1.join(df2, on=['name', 'age'])
# +----+---+-------+-----+
# |name|age|subject|parts|
# +----+---+-------+-----+
# |xxxx| 21| Maths| I|
# |xxxx| 21|Physics| I|
# |yyyy| 22|English| I|
# |yyyy| 22|English| II|
# |yyyy| 22| French| I|
# |yyyy| 22| French| II|
# +----+---+-------+-----+
我通过将列作为列表传递给 for 循环并分解列表中每个元素的数据框来做到这一点
数据样本
df.show()
+----+---+--------------+-----+
|Name|age| subject|parts|
+----+---+--------------+-----+
|xxxx| 21| Maths,Physics| I|
|yyyy| 22|English,French| I,II|
+----+---+--------------+-----+
df.printSchema()
root
|-- Name: string (nullable = true)
|-- age: long (nullable = true)
|-- subject: string (nullable = true)
|-- parts: string (nullable = true)
数据转换
from pyspark.sql import functions as F
df.withColumn(
"subject", F.explode(F.split("subject", ","))
).withColumn(
"parts", F.explode(F.split("parts", ","))
).show()
+----+---+-------+-----+
|Name|age|subject|parts|
+----+---+-------+-----+
|xxxx| 21| Maths| I|
|xxxx| 21|Physics| I|
|yyyy| 22|English| I|
|yyyy| 22|English| II|
|yyyy| 22| French| I|
|yyyy| 22| French| II|
+----+---+-------+-----+