将多个数组列拆分为行

问题描述

这是一个

相同的问题

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