pypark提取的嵌套JSON数组无法正常工作

时间:2020-08-25 16:20:47

标签: arrays json dataframe pyspark nested

我正在尝试读取嵌套的json,但是根据我先前搜索过的许多地方显示的结果,结果不是预期的。

json:

{'Folders': 
[
    {'Id': 1, 'Name': 'Surveys'},
    {'Id': 44, 'Name': 'EERM - Evaluaci\xf3n de Proveedores'},
    {'Id': 8, 'Name': 'Encuesta para demo'},
    {'Id': 9, 'Name': 'RAS-DataAnalytics'},
    {'Id': 2, 'Name': 'Voxco Training'},
    {'Id': 10, 'Name': 'Cliente 1'},
    {'Id': 13, 'Name': 'Demo'},
    {'Id': 28, 'Name': 'Demo 6'},
    {'Id': 11, 'Name': 'A\xf1o 1'},
    {'Id': 46, 'Name': 'Proveedores de Bienes o Productos'},
    {'Id': 45, 'Name': 'Proveedores de Servicios'}
]

}

架构:

>>> df.printSchema()
root
 |-- Folders: array (nullable = true)
 |    |-- element: struct (containsNull = true)
 |    |    |-- Id: long (nullable = true)
 |    |    |-- Name: string (nullable = true)

选择: 我得到的内容:

>>> df.select("Folders.Id").show()
+--------------------+
|                  Id|
+--------------------+
|[1, 44, 8, 9, 2, ...|
+--------------------+

我期望的是

+------+
|    Id|
+------+
| 1    |
+------+
| 44   |
+------+
| 8    |
+------+
| ...  |
+------+


我正在使用pyspark 2.4和python 2.7 我不知道我在做什么错。有什么想法吗?

2 个答案:

答案 0 :(得分:1)

由于Folders是一个由1个元素组成的数组,因此其所有值将被推断为一行。

要将其爆炸到多行,请尝试以下操作-

p = df.selectExpr("inline_outer(Folders)")
p.select("id").show()
+------+
|    Id|
+------+
| 1    |
+------+
| 44   |
+------+
| 8    |
+------+
| ...  |
+------+

答案 1 :(得分:1)

我认为pyspark explode功能就是您想要的。

from pyspark.sql.functions import explode, col

js = [{'Folders': 
[
    {'Id': 1, 'Name': 'Surveys'},
    {'Id': 44, 'Name': 'EERM - Evaluaci\xf3n de Proveedores'},
    {'Id': 8, 'Name': 'Encuesta para demo'},
    {'Id': 9, 'Name': 'RAS-DataAnalytics'},
    {'Id': 2, 'Name': 'Voxco Training'},
    {'Id': 10, 'Name': 'Cliente 1'},
    {'Id': 13, 'Name': 'Demo'},
    {'Id': 28, 'Name': 'Demo 6'},
    {'Id': 11, 'Name': 'A\xf1o 1'},
    {'Id': 46, 'Name': 'Proveedores de Bienes o Productos'},
    {'Id': 45, 'Name': 'Proveedores de Servicios'}
]
}]

df = spark.read.json(sc.parallelize(js))
df = df.select(explode(col("Folders")).alias("Folders"))
df.select("Folders.Id").show()

返回以下内容:

+---+
| Id|
+---+
|  1|
| 44|
|  8|
|  9|
|  2|
| 10|
| 13|
| 28|
| 11|
| 46|
| 45|
+---+