【问题标题】:Parsing multiple json objects from a text file using Python使用 Python 从文本文件中解析多个 json 对象
【发布时间】:2018-08-09 21:09:26
【问题描述】:

我有一个 .json 文件,其中每一行都是一个对象。例如,前两行是:

{"review_id":"x7mDIiDB3jEiPGPHOmDzyw","user_id":"msQe1u7Z_XuqjGoqhB0J5g","business_id": ...}

{"review_id":"dDl8zu1vWPdKGihJrwQbpw","user_id":"msQe1u7Z_XuqjGoqhB0J5g","business_id": ...}

我曾尝试使用 ijson lib 进行如下处理:

with open(filename, 'r') as f:
    objects = ijson.items(f, 'columns.items')
    columns = list(objects) 

但是,我得到错误:

JSONError: Additional data

这似乎是由于多个对象我收到这样的错误。

在 Jupyter 中分析此类 Json 文件的推荐方法是什么?

提前谢谢你

【问题讨论】:

  • 你的整个文件真的是有效的 json 吗?还是只有每一行有效的json?
  • 如果没有更具体的 json,我无法给出答案,但您可以尝试通过使用 , 分隔 json 对象并将它们包装在 [] 中来将其转换为列表
  • 似乎每一行都是一个有效的 json 并且有数百万行。

标签: python json ijson


【解决方案1】:

如果这是完整的文件,则文件格式不正确。在大括号之间必须有一个逗号,并且应该以方括号开头和结尾。像这样:[{...},{...}]。对于您的数据,它看起来像:

[{"review_id":"x7mDIiDB3jEiPGPHOmDzyw","user_id":"msQe1u7Z_XuqjGoqhB0J5g","business_id": ...},
{"review_id":"dDl8zu1vWPdKGihJrwQbpw","user_id":"msQe1u7Z_XuqjGoqhB0J5g","business_id": ...}]

以下是一些如何清理文件的代码:

lastline = None

with open("yourfile.json","r") as f:
    lineList = f.readlines()
    lastline=lineList[-1]

with open("yourfile.json","r") as f, open("cleanfile.json","w") as g:
    for i,line in enumerate(f,0):
        if i == 0:
            line = "["+str(line)+","
            g.write(line)
        elif line == lastline:            
            g.write(line)
            g.write("]")
        else:
            line = str(line)+","
            g.write(line)

要正确读取 json 文件,您还可以考虑使用 pandas 库 (https://pandas.pydata.org/pandas-docs/stable/generated/pandas.read_json.html)。

import pandas as pd

#get a pandas dataframe object from json file
df = pd.read_json("path/to/your/filename.json")

如果您不熟悉 pandas,这里是快速入门,如何使用数据框对象:

df.head() #gives you the first rows of the dataframe
df["review_id"] # gives you the column review_id as a vector
df.iloc[1,:] # gives you the complete row with index 1
df.iloc[1,2] # gives you the item in row with index 1 and column with index 2 

【讨论】:

  • 问题是我有一个相当大的 json 文件,如果我尝试执行 pandas read_json 会导致内存错误。因此,我正在尝试遵循dataquest.io/blog/python-json-tutorial 的指示。再说一次,文件格式不正确。我应该找到一种方法将它们包装在用逗号分隔的方括号中。
  • 我刚刚添加了一些代码,您可以使用这些代码以正确的格式创建新的 json 文件。但是,如果您的文件对于 pandas 来说确实太大,我担心这需要一段时间。
  • 它比我预期的要快
  • 这是您接受的答案,还是您仍有一些问题?
【解决方案2】:

虽然每一行本身都是有效的 JSON,但您的文件作为一个整体却不是。因此,您无法一次性解析它,您必须遍历每一行将其解析为一个对象。

您可以将这些对象聚合到一个列表中,然后从那里对您的数据做任何您喜欢的事情:

import json
with open(filename, 'r') as f:
    object_list = []
    for line in f.readlines():
        object_list.append(json.loads(line))
    # object_list will contain all of your file's data

你可以把它作为一个列表理解来让它更pythonic:

with open(filename, 'r') as f:    
    object_list = [json.loads(line) 
                   for line in f.readlines()]
    # object_list will contain all of your file's data

【讨论】:

  • 我不确定说它是无效的 JSON 文件是否公平。例如,在我的用例而不是文件中,我有一个网络套接字。现在怎么样,你会说我有一个无效的 JSON 套接字吗? :) This answer 虽然对我有用。
  • JSON 只允许一个对象位于文档的根目录。你有两个。那是客观上无效的json。现在,话虽如此,拥有换行符分隔的 JSON 是一件很常见的事情。您只需将每一行作为不同的 JSON 对象读取,仅此而已。将整个事物视为单个对象将失败,因为您拥有多个对象。
  • 您链接的答案是一个更复杂的解决方案,当对象之间没有分隔符时,这是有保证的。如果您有幸在对象之间使用换行符,则应该利用它。
【解决方案3】:

您的文件中有多行,这就是它抛出错误的原因

import json

with open(filename, 'r') as f:
    lines = f.readlines()
    first = json.loads(lines[0])
    second = json.loads(lines[1])

这应该捕获两条线并正确加载它们

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-09-03
    • 1970-01-01
    • 2012-02-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多