Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Scala 在Spark中独立爆炸多列_Scala_Apache Spark - Fatal编程技术网

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