Apache spark 如何将一行数组平面映射为多行?

Apache spark 如何将一行数组平面映射为多行?,apache-spark,apache-spark-sql,Apache Spark,Apache Spark Sql,在解析了一些JSON之后,我得到了一列数组数据帧 scala> val jj =sqlContext.jsonFile("/home/aahu/jj2.json") res68: org.apache.spark.sql.DataFrame = [r: array<bigint>] scala> jj.first() res69: org.apache.spark.sql.Row = [List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)] 我想要一个R

在解析了一些JSON之后,我得到了一列数组数据帧

scala> val jj =sqlContext.jsonFile("/home/aahu/jj2.json")
res68: org.apache.spark.sql.DataFrame = [r: array<bigint>]
scala> jj.first()
res69: org.apache.spark.sql.Row = [List(0, 1, 2, 3, 4, 5, 6, 7, 8, 9)]
我想要一个RDD或一个有20行的数据帧

我不能在这里简单地使用flatMap-我不确定spark中的适当命令是什么:

scala> jj.flatMap(r => r)
<console>:22: error: type mismatch;
 found   : org.apache.spark.sql.Row
 required: TraversableOnce[?]
              jj.flatMap(r => r)
scala>jj.flatMap(r=>r)
:22:错误:类型不匹配;
找到:org.apache.spark.sql.Row
必需:可遍历一次[?]
jj.flatMap(r=>r)

您可以使用
DataFrame.explode
来实现您想要的。下面是我在spark shell中使用您的示例json数据所做的尝试

import scala.collection.mutable.ArrayBuffer
val jj1 = jj.explode("r", "r1") {list : ArrayBuffer[Long] => list.toList }
val jj2 = jj1.select($"r1")
jj2.collect

您可以参考API文档来了解更多的数据帧。explode

我已经用Spark 1.3.1测试过了 也可以使用Row.getAs函数:

import scala.collection.mutable.ArrayBuffer
val elementsRdd = jj.select(jj("r")).map(t=>t.getAs[ArrayBuffer[Long]](0)).flatMap(x=>x)
elementsRdd.count()
>>>Long = 20
elementsRdd.take(5)
>>>Array[Long] = Array(0, 1, 2, 3, 4)

在Spark 1.3+中,您可以直接在感兴趣的列上使用
explode
功能:

import org.apache.spark.sql.functions.explode

jj.select(explode($"r"))

请发布原始的json示例和您想要的结果示例expecting@vvladymyrov在编辑中,你使用的是什么版本的spark/scala?我在本地模式下使用1.4并获取java.lang.ClassCastException:scala.collection.immutable.$colon$colon在尝试此操作时无法强制转换为scala.collection.mutable.ArrayBuffer
import org.apache.spark.sql.functions.explode

jj.select(explode($"r"))