如何在 PySpark 中转置 JSON 结构和数组

How to transpose JSON structs and arrays in PySpark

我正在将以下 Json 文件读入数据框。

{
  "details": {
    "box": [
      {
        "Touchdowns": "123",
        "field": "Texans"
      },
      {
        "Touchdowns": "456",
        "field": "Ravens"
      }
    ]
  },
  "name": "Team"
}

我如何操作它以获得以下输出?

Team Touchdowns
Texans 123
Ravens 456

我正在纠结是否需要 pivot/transpose 数据,或者是否有更优雅的方法。

将多行json读入spark

df = spark.read.json('/path/to/scores.json',multiLine=True)

架构

df:pyspark.sql.dataframe.DataFrame
    details:struct
        box:array
           element:struct
               Touchdowns:string
               field:string
     name:string

你想要的所有信息都在第一行,所以获取它并向下钻取细节和框,并将其作为你的新数据框。

spark.createDataFrame(df.first()['details']['box']).withColumnRenamed('field','Team').show()

输出

+----------+------+
|Touchdowns|  Team|
+----------+------+
|       123|Texans|
|       456|Ravens|
+----------+------+

您可以使用inline函数。

df = spark.read.load(json_file_path, format='json', multiLine=True)
df = df.selectExpr('inline(details.box)').withColumnRenamed('field', 'Team')
df.show(truncate=False)

您可以尝试使用 rdd 来获取 box list 的值。

输入JSON

jsonstr="""{
  "details": {
    "box": [
      {
        "Touchdowns": "123",
        "field": "Texans"
      },
      {
        "Touchdowns": "456",
        "field": "Ravens"
      }
    ]
  },
  "name": "Team"
}"""

现在使用 dictionary 的键将其转换为 rdd,如下所示 -

import json
box_rdd = sc.parallelize(json.loads(jsonstr)['details']['box'])
box_rdd.collect()

Output - [{'Touchdowns': '123', 'field': 'Texans'},
 {'Touchdowns': '456', 'field': 'Ravens'}]

最后用这个 box_rdd 创建数据框,如下所示 -

from pyspark.sql.types import *
schema = StructType([StructField('Touchdowns', StringType(), True), StructField('field', StringType(), True)])

df = spark.createDataFrame(data=box_rdd,schema=schema)
df.show()

+----------+------+
|Touchdowns| field|
+----------+------+
|       123|Texans|
|       456|Ravens|
+----------+------+