将 json 文件读入 Spark DataFrame

Posted

技术标签:

【中文标题】将 json 文件读入 Spark DataFrame【英文标题】:reading json file into Spark DataFrame 【发布时间】:2022-01-13 18:58:12 【问题描述】:

我正在尝试,但我将整个文件作为一行和一列获取我试图将其拆分为多列:

df = spark.read.json(sc.wholeTextFiles("HW2-DataSets/docs/output-0.json").values())
df.show()

这是我运行这行代码得到的输出:

+--------------------+
|              Images|
+--------------------+
|[[ricky4, 1634180...|
+--------------------+

这是创建的 DataFrame 的架构:

    root
 |-- Images: struct (nullable = true)
 |    |-- Z4ah9SemQjX2cKN187pX: struct (nullable = true)
 |    |    |-- artist: string (nullable = true)
 |    |    |-- created_at: long (nullable = true)
 |    |    |-- description: string (nullable = true)
 |    |    |-- download_url: string (nullable = true)
 |    |    |-- file_name: string (nullable = true)
 |    |    |-- id: string (nullable = true)
 |    |    |-- key_words: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true)
 |    |    |-- source: string (nullable = true)
 |    |    |-- tagged: boolean (nullable = true)
 |    |    |-- title: string (nullable = true)
 |    |-- Z552dVXF5vp80bAajYrn: struct (nullable = true)
 |    |    |-- artist: string (nullable = true)
 |    |    |-- created_at: long (nullable = true)
 |    |    |-- description: string (nullable = true)
 |    |    |-- download_url: string (nullable = true)
 |    |    |-- file_name: string (nullable = true)
 |    |    |-- id: string (nullable = true)
 |    |    |-- key_words: array (nullable = true)
 |    |    |    |-- element: string (containsNull = true)
 |    |    |-- source: string (nullable = true)
 |    |    |-- tagged: boolean (nullable = true)
 |    |    |-- title: string (nullable = true)
 |    |-- Z598cIDb79GPrC6VXbTb: struct (nullable = true)
           ....

我的目标是将图像中的每个对象放在一行中并分开列 这意味着例如“Z4ah9SemQjX2cKN187pX”的值:第一行中的艺术家,created_at ...和第二行中的“Z552dVXF5vp80bAajYrn”等。

我很新,每条评论都会有所帮助,谢谢。

更新


  "Images": 
    "Z4ah9SemQjX2cKN187pX": 
      "artist": "ricky4",
      "file_name": "mermaid_by_ricky4_d59jfzw-fullview.jpg",
      "created_at": 1634180503921,
      "description": "Hi folks! This is my latest work! So glad to be a part of the calendar project from my friend Dee  More details here! :thumb322291755: artistsforacure.deviantart.com… Inspired by: CLOCK DVA - Return to blue www.youtube.com/watch?v=rjfxI2…All resources: my own! Other purple artworks",
      "key_words": [
        "dark",
        "digital",
        "evil",
        "fantasy",
        "fishes",
        "lady",
        "light",
        "magic",
        "mermaid",
        "ocean",
        "sea",
        "utopia",
        "reflections"
      ],
      "source": "https://www.deviantart.com/",
      "title": "Mermaid",
      "tagged": false,
      "download_url": "",
      "id": "Z4ah9SemQjX2cKN187pX"
    ,
    "Z552dVXF5vp80bAajYrn": 

【问题讨论】:

我也尝试过使用这行代码,df = spark.read.json("HW2-DataSets/docs/output-0.json"),但得到相同的结果 你能分享一下 JSON 文件的样子吗? @RahulKumar 是的,我会更新问题。 【参考方案1】:

您可以首先使用多行选项读取 json 文件并将其作为数据框变量中的单列获取,然后您可以使用 columnname.* 对数据框变量使用 select 语句,它会给您一个数据框一行,其中每一行将包含具有单个值的列,如您的 json 中一样。

代码如下:

#read the json file
df = spark.read.option("multiline","true").json("HW2-DataSets/docs/output-0.json")
#used the select statement to see the output you want
from pyspark.sql.functions import *
df1 = df.select(col("Images.*"))
#do df1.show() to see the output
# I am using Databricks so I do display(df1)

#Convert Columns to rows (Updated)
from itertools import chain

m = create_map(list(chain(*(
        (lit(c), col(c)) for c in df1.columns))))

df2 = df1.withColumn('map', m)\
  .select(explode('map')).drop('map')

你可以看到如下输出:

【讨论】:

我试过了,但现在我得到了一个数据框,每一列都是对象,我已将这行代码添加到您的代码中:print((df_images.count(), len(df_images. columns))) # prints (1,444) 这意味着它为每个对象制作了一列,我试图使它成为 444 行,并且这些列是每个对象的键(艺术家,created_at...),你知道吗那怎么办? 查看更新的答案以获得您期望的结果。 我在最后一行代码中遇到异常。 AnalysisException:无法解析 '地图(' Z4ah9SemQjX2cKN187pX”,Z4ah9SemQjX2cKN187pX 'Z552dVXF5vp80bAajYrn',1XH4MCAOefT#8908,#图片AS 7998.Z6RxIsCeAmZW2s7FpFfh#Z6RxIsCeAmZW2s7FpFfh 8909,图片#7998.Z6VD11n6TuLxFpwuBnHt AS Z6VD11n6TuLxFpwuBnHt#8910,#图片AS 7998.Z6f7Ia2ZSwUnc6coiL5u Z6f7Ia2ZSwUnc6coiL5u #8911, Images#7998.Z6jsJ6GHGqCzVtYrWcvJ AS Z6jsJ6GHGqCzVtYrWcvJ#8912, ... 420 更多字段] +- 关系[Images#7998] json , 您在哪一行得到异常?您正在处理的实际数据是否存在不同之处,因为根据问题中存在的示例数据,它可以正常工作。 在 df2 行,我不相信,所以我从数据中发布了其中一个对象。

以上是关于将 json 文件读入 Spark DataFrame的主要内容,如果未能解决你的问题,请参考以下文章

使用 pyspark,如何将文件中单行的多个 JSON 文档读入数据框?

Spark 2.0 将 json 读入带有引号的数据帧中 - 与 spark 1.6 不同的行为......错误?

将带有嵌套标签的 XML 读入 Spark RDD,并转换为 JSON

如何将字符串中带有双引号的json文件加载到spark scala中的数据框中

从 S3 将嵌套文本文件读入 spark 时出现内存错误

Spark Scala 将文本文件读入 DataFrame