Scala 如何在Spark中将两个数组字段分解为多列?
我指的是类似的需求 我可以将该代码用于单个数组字段数据帧,但是,当我有多个数组字段数据帧时,我无法将这两个字段都转换为多个列 比如说, dataframe1Scala 如何在Spark中将两个数组字段分解为多列?,scala,apache-spark,apache-spark-sql,Scala,Apache Spark,Apache Spark Sql,我指的是类似的需求 我可以将该代码用于单个数组字段数据帧,但是,当我有多个数组字段数据帧时,我无法将这两个字段都转换为多个列 比如说, dataframe1 +--------------------+----------------------------------+----------------------------------+ | f1 |f2 |f3
+--------------------+----------------------------------+----------------------------------+
| f1 |f2 |f3 |
+--------------------+----------------------------------+----------------------------------+
|12 | null| null|
|13 | null| null|
|14 | null| null|
|15 | null| null|
|16 | null| null|
|17 | [[Hi, 256, Hello]]| [[a, b], [a, b, c],[a, b]]|
|18 | null| null|
|19 | null| null|
+--------------------+----------------------------------+----------------------------------+
我想将其转换为以下数据帧:
dataframe2
+--------------------+----------------------------------+----------------------------------+----------------------------------+
| f1 |f2_0 |f3_0 |f3_1 |
+--------------------+----------------------------------+----------------------------------+----------------------------------+
|12 | null| null| null|
|13 | null| null| null|
|14 | null| null| null|
|15 | null| null| null|
|16 | null| null| null|
|17 | [Hi, 256, Hello]| [a, b]| [a, b, c]|
|18 | null| null| null|
|19 | null| null| null|
+--------------------+----------------------------------+----------------------------------+----------------------------------+
我尝试了以下代码:
val dataframe2 = dataframe1.select(
col("f1") +: (0 until 2).map(i => col("f2")(i).alias(s"f2_$i")): _* +: (0 until 2).map(i => col("f3")(i).alias(s"f3_$i")): _*
)
但是它抛出了一个错误,表示在Scala中使用的第一个“*”
+:
将单个元素添加到列表中,它希望在第一个“*”之后出现“)”。它不能用于将两个列表连接在一起。相反,您可以按如下方式使用++
:
val cols = Seq(col("f1"))
++ (0 until 1).map(i => col("f2")(i).alias(s"f2_$i"))
++ (0 until 2).map(i => col("f3")(i).alias(s"f3_$i"))
val dataframe2 = dataframe1.select(cols: _*)
请注意,要使用这种方法,您需要提前知道列表中元素的数量。上面,我将f2列的2改为1。Shaido的答案已经正确,这个答案只是对它的一个增强。在这里,我只是添加了动态查找列的最大长度 如果列
f2
和f3
已经是数组,则相应的最大数组大小计算如下
val s1 = df.select(max(size(df("f2")))).first().getInt(0)
val s2 = df.select(max(size(df("f3")))).first().getInt(0)
否则,如果该列应根据分隔符拆分并进一步拆分为列,则首先计算大小,如下所示
val s1 = df.select(max(size(split(df("f2"), ",")))).first().getInt(0)
val s2 = df.select(max(size(split(df("f3"), ",")))).first().getInt(0)
然后我们可以在Shaido答案的map函数中使用s1
,s2
(0到s1)。map(……
谢谢你的解释。我有一个语法疑问。最后一个表达式在我的代码中是什么意思?我没有从参考链接中理解该部分。@user3243499:很高兴提供帮助。我想这里的答案比我能解释的更好: