Scala 在Spark中独立爆炸多列
我有一个模式,其中每一行包含多个数组列,我想独立地分解每个数组列 假设我们有以下列:Scala 在Spark中独立爆炸多列,scala,apache-spark,Scala,Apache Spark,我有一个模式,其中每一行包含多个数组列,我想独立地分解每个数组列 假设我们有以下列: **userId someString varA varB someBool 1 "example1" [0,2,5] [1,2,9] true 2 "example2" [1,20,5] [9,null,6] false 我想要一个输出: userId someString v
**userId someString varA varB someBool
1 "example1" [0,2,5] [1,2,9] true
2 "example2" [1,20,5] [9,null,6] false
我想要一个输出:
userId someString varA varB someBool
1 "example1" 0 null true
1 "example1" 2 null true
1 "example1" 5 null true
1 "example1" 1 null true
1 "example1" 20 null true
1 "example1" 5 null true
2 "example2" null 1 false
2 "example2" null 2 false
2 "example2" null 9 false
2 "example2" null 9 false
2 "example2" null null false
2 "example2" null 6 false
想法
(哦,我试着一般性地解决这个问题,这样我就不必随着模式的变化而更新代码,而且因为实际的模式有点大…)
PS-道具非常相似,但不同的问题,从中我无耻地窃取了示例数据
编辑:@oliik获胜,但是,如果能通过
df.flatMap
(主要是因为我仍然不去摸索flatMap
)你总是可以通过编程方式生成选择
val df = Seq(
(1, "example1", Seq(0,2,5), Seq(Some(1),Some(2),Some(9)), true),
(2, "example2", Seq(1,20,5), Seq(Some(9),Option.empty[Int],Some(6)), false)
).toDF("userId", "someString", "varA", "varB", "someBool")
val arrayColumns = df.schema.fields.collect {
case StructField(name, ArrayType(_, _), _, _) => name
}
val dfs = arrayColumns.map { expname =>
val columns = df.schema.fields.map {
case StructField(name, ArrayType(_, _), _, _) if expname == name => explode(df.col(name)) as name
case StructField(name, ArrayType(_, _), _, _) => lit(null) as name
case StructField(name, _, _, _) => df.col(name)
}
df.select(columns:_*)
}
dfs.reduce(_ union _).show()
我想知道这是否可以动态完成?如何获得例如此行
2“example2”1 null true
?在源表中,someBool==false userId==2@ollik1输入错误:POkay,超级酷。我能让你解释一下在选择中发生了什么使这起作用吗?你能解释一下这个案例吗?想法是“循环”通过数组列并对所有列应用以下内容:1)如果该列是正在循环的数组列,则分解该列2)如果该列是其他数组列,则使用null
值替换该列3)如果该列不是数组列,则保持原样。这将提供select(“userId”、“someString”、explode(“varA”)、lit(null)、“someBool”)
和select(“userId”、“someString”、lit(null)、explode(“varB”)、“someBool”)
。最后,我们合并这些数据帧,我得到的是它,但不是这个:ArrayType(,u),u,u)这个u,它自己。我会努力的,我很喜欢。增加了我所缺少的一个方面。做得好。它用于捕获所有数组类型,而不考虑参数。ArrayType接受两个参数,元素类型和包含null。在这种情况下,我们总是希望匹配,因此忽略值
+------+----------+----+----+--------+
|userId|someString|varA|varB|someBool|
+------+----------+----+----+--------+
| 1| example1| 0|null| true|
| 1| example1| 2|null| true|
| 1| example1| 5|null| true|
| 2| example2| 1|null| false|
| 2| example2| 20|null| false|
| 2| example2| 5|null| false|
| 1| example1|null| 1| true|
| 1| example1|null| 2| true|
| 1| example1|null| 9| true|
| 2| example2|null| 9| false|
| 2| example2|null|null| false|
| 2| example2|null| 6| false|
+------+----------+----+----+--------+