基于多列将行分成多行

时间:2018-06-07 19:10:50

标签: apache-spark dataframe

我在spark中有一个数据框:

id   |   itemid   |   itemquant   |  itemprice 
-------------------------------------------------
 A   |    1,2,3   |   2,2,1       |  30,19,10
 B   |    3,5     |   5,8         |  18,40

这里所有列都是字符串数据类型。

如何在多个列中使用explode功能并创建如下所示的新数据框:

id   |   itemid   |   itemquant   |  itemprice 
-------------------------------------------------
 A   |     1      |      2        |     30
 A   |     2      |      2        |     19
 A   |     3      |      1        |     10
 B   |     3      |      5        |     18
 B   |     5      |      8        |     40

此外,在新数据框中,所有列都是字符串数据类型。

1 个答案:

答案 0 :(得分:1)

你需要一个UDF:

val df = Seq(
  ("A","1,2,3","2,2,1","30,19,10"),
  ("B","3,5","5,8","18,40")
).toDF("id","itemid","itemquant","itemprice")

val splitAndZip = udf((col1:String,col2:String,col3:String) => {
  col1.split(',').zip(col2.split(',')).zip(col3.split(',')).map{case ((a,b),c) => (a,b,c)}
})

df
  .withColumn("tmp",explode(splitAndZip($"itemId",$"itemquant",$"itemprice")))
  .select(
    $"id",
    $"tmp._1".as("itemid"),
    $"tmp._2".as("itemquant"),
    $"tmp._3".as("itemprice")
  )
  .show()

+---+------+---------+---------+
| id|itemid|itemquant|itemprice|
+---+------+---------+---------+
|  A|     1|        2|       30|
|  A|     2|        2|       19|
|  A|     3|        1|       10|
|  B|     3|        5|       18|
|  B|     5|        8|       40|
+---+------+---------+---------+