需要帮助用scala解析奇怪的JSON

时间:2017-06-13 01:25:13

标签: json scala apache-spark dataframe

我正在解析json以在scala中激活数据帧。我有一个嵌套的json文件,包含50种不同家庭用品的不同记录。在JSON上我试图解析设备标签如下:

"equipment":[{"tv":[""]}]

由于此项目名称(例如:在这种情况下为tv)正在成为列名而不是值。

理想情况下,此标记应该是,

"equipment":["tv"]

有没有办法解析这种类型的JSON标记/内容?

由于这个原因,数据帧架构显示为:

 |-- equipment: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- ac: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true)
 |    |    |-- tv: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true)

你可以在哪里看到(上图)ac& tv正在成为列标题。而不是我需要它们显示为值。数据框应如下所示:

+----------+
|equipment |
+----------+
|tv        |
|ac        |
+----------+

1 个答案:

答案 0 :(得分:0)

一个简单的explode函数应该已经为你完成了这个技巧,但是看看你的schema,两个explode函数就可以了。

val newdf = dataframe.withColumn("equipment", explode($"equipment"))
newdf.withColumn("equipment", explode(array($"equipment.*"))).show(false)

通过这些步骤,您应该在问题中获得所需的结果。

<强>被修改

从您的评论中,您似乎试图爆炸fieldNames而不是值。所以下面的代码应该可以工作

val newdf = dataframe.withColumn("equipment", explode($"equipment"))
sc.parallelize(newdf.select("equipment.*").schema.fieldNames.toSeq).toDF("equipment").show(false)

这是我正在测试的完整代码

val data = Seq("""{"equipment":[{"tv":[""],"ac":[""]}]}""")
val dataframe = sqlContext.read.json(sc.parallelize(data))
dataframe.printSchema()
val newdf = dataframe.withColumn("equipment", explode($"equipment"))
sc.parallelize(newdf.select("equipment.*").schema.fieldNames.toSeq).toDF("equipment").show(false)

打印的架构与您的匹配

root
 |-- equipment: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- ac: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true)
 |    |    |-- tv: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true)

我得到的结果与您的预期结果匹配

+---------+
|equipment|
+---------+
|ac       |
|tv       |
+---------+