Python:尝试反序列化一个文件中的多个JSON对象,每个对象跨越多个但间隔一致的行数

Python:尝试反序列化一个文件中的多个JSON对象,每个对象跨越多个但间隔一致的行数,python,json,Python,Json,好吧,经过近一周的研究,我打算试一试。我有一个如下所示的文本文件(以3个单独的json对象为例,但该文件有50K个这样的对象): 我知道如何使用pythonjson库处理JSON对象,但如何通过读取该文件创建50000个不同的JSON对象是我面临的一个挑战。(也许我甚至没有正确地考虑这一点,但最终我需要反序列化并加载到数据库中)我尝试了itertools,认为我需要一个生成器,以便能够使用: with open(file) as f: for line in itertools.isli

好吧,经过近一周的研究,我打算试一试。我有一个如下所示的文本文件(以3个单独的json对象为例,但该文件有50K个这样的对象):

我知道如何使用pythonjson库处理JSON对象,但如何通过读取该文件创建50000个不同的JSON对象是我面临的一个挑战。(也许我甚至没有正确地考虑这一点,但最终我需要反序列化并加载到数据库中)我尝试了itertools,认为我需要一个生成器,以便能够使用:

with open(file) as f:
    for line in itertools.islice(f, 0, 7): #since every 7 lines is a json object
        jfile = json.load(line)
但上述方法显然行不通,因为它不是将7行作为单个json对象读取,我也不知道如何在整个文件上迭代并加载单个json对象

下面是我可以切分的列表:

list(open(file))[:7]
任何帮助都将不胜感激


非常接近我所需要的,我认为这是一步之遥,但仍然在迭代中挣扎。这将最终使我得到所有数据帧的迭代打印输出,但我如何制作它,以便我能够捕获一个巨大的数据帧,其中所有片段基本上是连接在一起的?然后我可以将最终的数据帧导出到csv等(还有没有更好的方法将结果上传到数据库中,而不是先创建一个巨大的数据帧?)


改为额外加载6行,并将字符串传递到
json.loads()

json.load()
将不仅仅读取文件中的下一个对象,而且
islice(f,0,7)
将只读取前7行,而不是以7行块读取文件

您可以在生成器中将读取文件包装为大小为N的块:

from itertools import islice, chain

def lines_per_n(f, n):
    for line in f:
        yield ''.join(chain([line], itertools.islice(f, n - 1)))
然后用它将输入文件分块:

with open(file) as f:
    for chunk in lines_per_n(f, 7):
        jfile = json.loads(chunk)

        # do something with jfile
或者,如果您的块的长度可变,请一直读取,直到您有了解析的内容:

with open(file) as f:
    for line in f:
        while True:
            try:
                jfile = json.loads(line)
                break
            except ValueError:
                # Not yet a complete JSON value
                line += next(f)

        # do something with jfile

如其他地方所述,一般的解决方案是将文件分块读取,将每一块附加到最后一块,然后尝试解析新的块。如果它没有解析,请继续,直到得到可以解析的内容为止。一旦你有了解析的东西,返回它,然后重新启动这个过程。重复冲洗泡沫,直到数据用完

下面是一个简洁的生成器,它将执行以下操作:

def load_json_multiple(segments):
    chunk = ""
    for segment in segments:
        chunk += segment
        try:
            yield json.loads(chunk)
            chunk = ""
        except ValueError:
            pass
像这样使用它:

with open('foo.json') as f:
   for parsed_json in load_json_multiple(f):
      print parsed_json

我希望这能有所帮助。

如果我很愚蠢,请原谅我;但不是每5行就有一个json对象吗?不管怎么说,基于你的示例。@daveL我明白你的意思,我可能措辞不好,但我的意思是能够加载构成一个json对象的每个块,然后能够单独处理每个块。至于你的第二个解决方案,
JSONDecoder.raw_decode
基本上就是为你这样做的。@stephan然而,请注意,
JSONDecoder.raw\u decode
目前无法处理。@stephan:在某种程度上,是的。我使用了这两种方法,具体取决于文件的结构。如果对象由换行符分隔,并且大多数代码段都是短的一行代码,那么异常处理程序的方法就很好而且很快了。@stephan:请注意,
JSONDecoder.raw\u decode
仅适用于输入字符串,而不是文件对象,因此您必须自己处理读取行的缓冲。当原始解码器找到对象时,您可以读取x行,尝试解析,并根据需要添加行。但当用新行分隔时,我的第二种方法就方便多了。这真是太棒了,非常值得赞赏。我真的很喜欢能够调用lines\u per\n函数,然后我就可以处理这个块了。很抱歉这个愚蠢的问题,因为我仍在学习如何应用生成器,但我如何才能将处理应用到文件中的所有对象,而不仅仅是第一个对象?换句话说,在第一个块上运行进程,然后在后续块上自动运行进程,直到文件结束?
with open(file) as f:
    for line in f:
        while True:
            try:
                jfile = json.loads(line)
                break
            except ValueError:
                # Not yet a complete JSON value
                line += next(f)

        # do something with jfile
def load_json_multiple(segments):
    chunk = ""
    for segment in segments:
        chunk += segment
        try:
            yield json.loads(chunk)
            chunk = ""
        except ValueError:
            pass
with open('foo.json') as f:
   for parsed_json in load_json_multiple(f):
      print parsed_json