如何将多列对分解为多行?
我有一个包含以下内容的数据框
client, type, address, type_2, address_2
abc, home, 123 Street, business, 456 Street
我想在后面加上一个最终的数据框
client, type, address
abc, home, 123 Street
abc, business, 456 Street
我在下面尝试使用此代码,但它返回了4条记录,而不是我想要的两条记录
df
.withColumn("type", explode(array("type", "type_2")))
.withColumn("address", explode(array("address", "address_2")))
我可以对两个单独的数据框执行此操作并执行并集操作,但是我想查看是否有另一种方法可以在单个数据框内进行操作
谢谢
答案 0 :(得分:4)
您可以使用结构来实现:
df
.withColumn("str",explode(
array(
struct($"type",$"address"),
struct($"type_2".as("type"),$"address_2".as("address"))))
)
.select($"client",$"str.*")
.show()
给予
+------+--------+----------+
|client| type| address|
+------+--------+----------+
| abc| home|123 Street|
| abc|business|456 Street|
+------+--------+----------+
答案 1 :(得分:0)
这是我用于复杂转换的技术-在数据帧上映射记录,并使用scala进行任何复杂度的转换。
在这里,我很难对2行的创建进行编码,但是可以根据需要在此处放置任何逻辑来爆炸行。我使用了flatmap将行数组拆分为行。
val df = spark.createDataFrame(Seq(("abc","home","123 Street","business","456 Street"))).toDF("client", "type", "address","type_2","address_2")
df.map{ r =>
Seq((r.getAs[String]("client"),r.getAs[String]("type"),r.getAs[String]("address")),
(r.getAs[String]("client"),r.getAs[String]("type_2"),r.getAs[String]("address_2")))
}.flatMap(identity(_)).toDF("client", "type", "address").show(false)
结果
+------+--------+----------+
|client|type |address |
+------+--------+----------+
|abc |home |123 Street|
|abc |business|456 Street|
+------+--------+----------+