我正在解析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 |
+----------+
答案 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 |
+---------+