【问题标题】:How do I flatMap a row of arrays into multiple rows?如何将一行数组平面映射成多行?
【发布时间】:2015-08-30 06:24:20
【问题描述】:

解析一些 json 后,我有一个单列的数组 DataFrame

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)]

我想将每一行分解成几行。怎么样?

编辑:

原始json文件:

{"r": [0,1,2,3,4,5,6,7,8,9]}
{"r": [0,1,2,3,4,5,6,7,8,9]}

我想要一个 RDD 或 20 行的 DataFrame。

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

scala> jj.flatMap(r => r)
<console>:22: error: type mismatch;
 found   : org.apache.spark.sql.Row
 required: TraversableOnce[?]
              jj.flatMap(r => r)

【问题讨论】:

  • 请发布原始json示例和您期望的结果示例
  • @vvladymyrov 它正在编辑中

标签: apache-spark apache-spark-sql


【解决方案1】:

您可以使用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文档了解更多DataFrame.explode

【讨论】:

  • 你使用的是什么版本的 spark/scala?我在本地模式下使用 1.4 并得到 java.lang.ClassCastException: scala.collection.immutable.$colon$colon cannot be cast to scala.collection.mutable.ArrayBuffer 当我尝试这个时
【解决方案2】:

我已经使用 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)

【讨论】:

    【解决方案3】:

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

    import org.apache.spark.sql.functions.explode
    
    jj.select(explode($"r"))
    

    【讨论】:

      猜你喜欢
      • 2016-04-09
      • 2020-04-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-08-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多