Scala Spark将多列对爆炸成行

时间:2020-01-22 19:33:58

标签: scala apache-spark

如何将多列对分解为多行?

我有一个包含以下内容的数据框

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")))

我可以对两个单独的数据框执行此操作并执行并集操作,但是我想查看是否有另一种方法可以在单个数据框内进行操作

谢谢

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|
+------+--------+----------+