问题描述
这是一个与
相同的问题Pyspark: Split multiple array columns into rows
但是我想知道如何在Scala中做到这一点
对于这样的数据框,
+---+---------+---------+---+
| a| b| c| d|
+---+---------+---------+---+
| 1|[1,2,3]|[,8,9] |foo|
+---+---------+---------+---+
我想要采用以下格式
+---+---+-------+------+
| a| b| c | d |
+---+---+-------+------+
| 1| 1| None | foo |
| 1| 2| 8 | foo |
| 1| 3| 9 | foo |
+---+---+-------+------+
在scala中,我知道有一个爆炸功能,但是我认为它在这里不适用。
我尝试过
import org.apache.spark.sql.functions.arrays_zip
但是我得到一个错误,说arrays_zip不是org.apache.spark.sql.functions的成员,尽管它显然是https://spark.apache.org/docs/latest/api/java/org/apache/spark/sql/functions.html
中的函数解决方法
以下答案可能对您有帮助
import org.apache.spark.sql.types._
import org.apache.spark.sql.Row
import org.apache.spark.sql.functions._
val arrayData = Seq(
Row(1,List(1,2,3),List(0,8,9),"foo"))
val arraySchema = new StructType().add("a",IntegerType).add("b",ArrayType(IntegerType)).add("c",ArrayType(IntegerType)).add("d",StringType)
val df = spark.createDataFrame(spark.sparkContext.parallelize(arrayData),arraySchema)
df.select($"a",$"d",explode($"b",$"c")).show(false)
val zip = udf((x: Seq[Int],y: Seq[Int]) => x.zip(y))
df.withColumn("vars",explode(zip($"b",$"c"))).select($"a",$"vars._1".alias("b"),$"vars._2".alias("c")).show()
/*
+---+---+---+---+
| a| d| b| c|
+---+---+---+---+
| 1|foo| 1| 0|
| 1|foo| 2| 8|
| 1|foo| 3| 9|
+---+---+---+---+
*/