输入
Column1 column2. column3
(1,2) (xyz,abc). (123,456)
输出应为
Column1 column2 column3
1. Xyz. 123
2. Abc. 456
我需要在数据帧中拆分数据。由于每列的第一个元素应该排成一行,第二列的元素排成第二列,依此类推,该数据的元素将被拆分并随后成为另一行。
答案 0 :(得分:1)
如果您使用的是最新版本的Spark,arrays_zip
将帮助您完成所需的工作:
// define test dataset
val df = spark.createDataset(List(("(1,2)","(xyz,abc)","(123,456)")))
.toDF("Column1","Column2","Column3")
df.show
+-------+---------+---------+
|Column1| Column2| Column3|
+-------+---------+---------+
| (1,2)|(xyz,abc)|(123,456)|
+-------+---------+---------+
使用此数据集,您可以将所有定界的文本值拆分为数组:
val reshape_cols = df.columns
.map(c => split(regexp_replace(col(c),"[()]",""),",").as(c))
val reshaped_df = df.select(reshape_cols:_*)
reshaped_df.show
+-------+----------+----------+
|Column1| Column2| Column3|
+-------+----------+----------+
| [1, 2]|[xyz, abc]|[123, 456]|
+-------+----------+----------+
现在有了数组,您可以使用arrays_zip
来生成struct类型数组的单列
val zipped_df = reshaped_df
.select(arrays_zip(reshaped_df.columns.map(col):_*).as("value"))
zipped_df.show(false)
+------------------------------+
|value |
+------------------------------+
|[[1, xyz, 123], [2, abc, 456]]|
+------------------------------+
现在您有了一个结构数组,可以使用explode将您的单行转换为多行:
val final_df = zipped_df
.select(explode('value).as("s"))
.select(df.columns.map(c => 's(c).as(c)):_*)
final_df.show
+-------+-------+-------+
|Column1|Column2|Column3|
+-------+-------+-------+
| 1| xyz| 123|
| 2| abc| 456|
+-------+-------+-------+