在 Python 中读取大量 json 文件?

Posted

技术标签:

【中文标题】在 Python 中读取大量 json 文件?【英文标题】:Reading huge number of json files in Python? 【发布时间】:2017-05-29 01:26:42 【问题描述】:

这不是关于读取大型 JSON 文件,而是关于以最有效的方式读取大量 JSON 文件。

问题

我正在使用来自Million song dataset 的last.fm 数据集。 数据以一组 JSON 编码的文本文件的形式提供,其中的键是:track_id、艺术家、标题、时间戳、相似和标签。

目前,在经历了几个选项后,我正在通过以下方式将它们读入 pandas,因为这是最快的,如 here 所示:

import os
import pandas as pd
try:
    import ujson as json
except ImportError:
    try:
        import simplejson as json
    except ImportError:
        import json


# Path to the dataset
path = "../lastfm_train/"

# Getting list of all json files in dataset
all_files = [os.path.join(root,file) for root, dirs, files in os.walk(path) for file in files if file.endswith('.json')] 

data_list=[json.load(open(file)) for file in all_files]
df = pd.DataFrame(data_list, columns=['similars', 'track_id'])
df.set_index('track_id', inplace=True)

当前方法读取子集(不到一秒内读取完整数据集的 1%)。然而,阅读完整的火车集太慢了,而且需要很长时间(我也等了几个小时)才能阅读,并且已经成为进一步任务的瓶颈,例如 question here 中所示。

我还使用ujson 来提高解析json 文件的速度,这可以从this question here 中明显看出

更新 1 使用生成器推导而不是列表推导。

data_list=(json.load(open(file)) for file in all_files)

【问题讨论】:

好像你没有足够的RAM,它开始使用SWAP,最简单的解决方案是获得更多的RAM。 @FranciscoCouzo 也许是最简单的......但绝对不是最便宜的! :D 我已经有 16Gigs 了,我认为这对于读取这样的普通数据集来说绝对足够了。有没有更好的方法来读取这么多的 json 文件? 一个接一个地读取所有 JSON,然后将您想要的列写入 CSV 将是微不足道的,几乎不占用 RAM,并简化格式,以便 Pandas、Numpy 或其他任何可以读取它以一种可能更有效的方式聚集在一起。 来自labrosa.ee.columbia.edu/millionsong/lastfm "因为遍历 JSON 文件效率低下,而且大多数人只会处理相似性或标签,我们提供了两个 SQLite 数据库 数据。"。下载然后pd.read_sql('SELECT similars, track_id FROM ...', ...) 【参考方案1】:

如果您需要多次读取和写入数据集,您可以尝试将.json 文件转换为更快的格式。例如,在 pandas 0.20+ 中,您可以尝试使用 .feather 格式。

【讨论】:

【参考方案2】:

我会在文件和 yield 你想要的两列上构建一个迭代器。

然后您可以使用该迭代器实例化 DataFrame

import os
import json
import pandas as pd

# Path to the dataset
path = "../lastfm_train/"

def data_iterator(path):
    for root, dirs, files in os.walk(path):
        for f in files:
            if f.endswith('.json'):
                fp = os.path.join(root,f)
                with open(fp) as o:
                    data = json.load(o)
                yield "similars" : data["similars"], "track_id": data["track_id"]


df = pd.DataFrame(data_iterator(path))
df.set_index('track_id', inplace=True)

这样你只检查你的文件列表一次,你不会在传递给DataFrame之前和之后复制数据

【讨论】:

请查看更新,已经使用生成器理解。 使用我发布的代码(带有原生包json),我在104 seconds中加载了完整的火车集数据集 我的代码和您的代码在 1.04 秒内加载子集(1%),因此,预计完整加载大约 100 秒。但是,在我的机器上,您的代码需要 406 秒,而我的代码需要 473 秒。我正在使用具有 16GB RAM 的 Macbook Pro 2015 版本。您正在使用什么野兽来完美地扩展到完整的数据集? :-) 我在这样的专用服务器上工作:ovh.co.uk/dedicated_servers/… 认真的吗?我希望你在开玩笑。

以上是关于在 Python 中读取大量 json 文件?的主要内容,如果未能解决你的问题,请参考以下文章

python读取json格式文件大量数据,以及python字典和列表嵌套用法详解

尝试在 Python 包中读取 JSON 文件

python 从setup.json读取的示例setup.py

Python从数据库读取数据写入json格式文件

Python setup.py 在 egg 中包含 .json 文件

使用文件路径读取另一个python文件中的.py文件变量[重复]