如何展开 DataFrame 中的数组(来自 JSON)?

Posted

技术标签:

【中文标题】如何展开 DataFrame 中的数组(来自 JSON)?【英文标题】:How to unwind array in DataFrame (from JSON)? 【发布时间】:2017-04-23 11:13:35 【问题描述】:

RDD 中的每条记录都包含一个 json。我正在使用 SQLContext 从 Json 创建一个 DataFrame,如下所示:

val signalsJsonRdd = sqlContext.jsonRDD(signalsJson)

下面是架构。 datapayload 是一个项目数组。我想分解项目数组以获得一个数据框,其中每一行都是来自 datapayload 的项目。我试图根据this 的答案做一些事情,但似乎我需要在 case Row(arr: Array[...]) 语句中对项目的整个结构进行建模。我可能错过了一些东西。

val payloadDfs = signalsJsonRdd.explode($"data.datapayload") 
    case org.apache.spark.sql.Row(arr: Array[String]) =>  arr.map(Tuple1(_)) 

上面的代码抛出了一个 scala.MatchError,因为实际 Row 的类型与 Row(arr: Array[String]) 非常不同。可能有一种简单的方法可以做我想做的事,但我找不到。请帮忙。

下面给出的架构

signalsJsonRdd.printSchema()

root
 |-- _corrupt_record: string (nullable = true)
 |-- data: struct (nullable = true)
 |    |-- dataid: string (nullable = true)
 |    |-- datapayload: array (nullable = true)
 |    |    |-- element: struct (containsNull = true)
 |    |    |    |-- Reading: struct (nullable = true)
 |    |    |    |    |-- A2DPActive: boolean (nullable = true)
 |    |    |    |    |-- Accuracy: double (nullable = true)
 |    |    |    |    |-- Active: boolean (nullable = true)
 |    |    |    |    |-- Address: string (nullable = true)
 |    |    |    |    |-- Charging: boolean (nullable = true)
 |    |    |    |    |-- Connected: boolean (nullable = true)
 |    |    |    |    |-- DeviceName: string (nullable = true)
 |    |    |    |    |-- Guid: string (nullable = true)
 |    |    |    |    |-- HandsFree: boolean (nullable = true)
 |    |    |    |    |-- Header: double (nullable = true)
 |    |    |    |    |-- Heading: double (nullable = true)
 |    |    |    |    |-- Latitude: double (nullable = true)
 |    |    |    |    |-- Longitude: double (nullable = true)
 |    |    |    |    |-- PositionSource: long (nullable = true)
 |    |    |    |    |-- Present: boolean (nullable = true)
 |    |    |    |    |-- Radius: double (nullable = true)
 |    |    |    |    |-- SSID: string (nullable = true)
 |    |    |    |    |-- SSIDLength: long (nullable = true)
 |    |    |    |    |-- SpeedInKmh: double (nullable = true)
 |    |    |    |    |-- State: string (nullable = true)
 |    |    |    |    |-- Time: string (nullable = true)
 |    |    |    |    |-- Type: string (nullable = true)
 |    |    |    |-- Time: string (nullable = true)
 |    |    |    |-- Type: string (nullable = true)

【问题讨论】:

看起来很像***.com/q/43411832/1305344。 【参考方案1】:

tl;dr explode 函数是你的朋友(或我最喜欢的 flatMap)。

explode 函数为给定数组或映射列中的每个元素创建一个新行。

类似下面的东西应该可以工作:

signalsJsonRdd.withColumn("element", explode($"data.datapayload"))

见functions对象。

【讨论】:

谢谢,成功了。你能帮我理解函数explode和方法signalsRdd.explode有什么区别吗?我正在使用该方法,因为这是我在每个示例中看到的,但无法使其发挥作用。

以上是关于如何展开 DataFrame 中的数组(来自 JSON)?的主要内容,如果未能解决你的问题,请参考以下文章

如何从js中的数组中删除元素[元素来自mongodb] [重复]

如何从js中的数组中删除元素[元素来自mongodb] [重复]

js中的展开运算符

在 Scala 中使用来自另一个没有数组列的 DataFrame 的数组类型列创建 Spark DataFrame 的有效方法是啥?

如何在 pandas DataFrame 中恢复\展开多索引

Js展开运算符和嵌套数组