加快将 json 数据加载到数据框中
Posted
技术标签:
【中文标题】加快将 json 数据加载到数据框中【英文标题】:Speed Up Loading json data into dataframe 【发布时间】:2018-04-07 00:43:24 【问题描述】:我正在尝试使用下面的代码将一组非常大的嵌套 json 文件读入 pandas 数据帧。这是几百万条记录,它是来自 yelp 学术数据集的“评论”文件。
有人知道更快的方法吗?
是否可以只加载 json 记录的样本?我可能只需要几十万条记录就可以了。
另外,我可能不需要 review.json 文件中的所有字段,我可以只加载其中的一个子集,例如 user_id、business_id、stars 吗?那会加快速度吗?
我会发布示例数据,但我什至无法完成加载。
代码:
df_review = pd.read_json('dataset/review.json', lines=True)
更新:
代码:
reviews = ''
with open('dataset/review.json','r') as f:
for line in f.readlines()[0:1000]:
reviews += line
testdf = pd.read_json(reviews,lines=True)
错误:
---------------------------------------------------------------------------
UnicodeDecodeError Traceback (most recent call last)
<ipython-input-18-8e4a45990905> in <module>()
5 reviews += line
6
----> 7 testdf = pd.read_json(reviews,lines=True)
/Users/anaconda/lib/python2.7/site-packages/pandas/io/json.pyc in read_json(path_or_buf, orient, typ, dtype, convert_axes, convert_dates, keep_default_dates, numpy, precise_float, date_unit, encoding, lines)
273 # commas and put it in a json list to make a valid json object.
274 lines = list(StringIO(json.strip()))
--> 275 json = u'[' + u','.join(lines) + u']'
276
277 obj = None
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 357: ordinal not in range(128)
更新 2:
import sys
reload(sys)
sys.setdefaultencoding('utf-8')
reviews = ''
with open('dataset/review.json','r') as f:
for line in f.readlines()[0:1000]:
reviews += line
testdf = pd.read_json(reviews,lines=True)
【问题讨论】:
【参考方案1】:加速那条线将是一项挑战,因为它已经超级优化了。
我会首先检查您是否可以从提供者那里获得更少的行/数据,正如您所提到的。
如果您之前可以处理数据,我建议您先将其转换为 JSON(甚至尝试不同的解析器,它们对每个数据集结构的性能都会发生变化),而不是只保存您需要的数据,并使用此输出调用 pandas方法。
Here你可以找到一些json解析器的基准,记住你应该对你的数据进行测试,这篇文章是2015年的。
【讨论】:
【参考方案2】:如果您的文件按照您的暗示将 json 对象行分隔,这可能会起作用。只需读取文件的前 1000 行,然后使用 pandas 读取。
import pandas as pd
reviews = ''
with open('dataset/review.json','r') as f:
for line in f.readlines()[0:1000]:
reviews += line
pd.read_json(reviews,lines=True)
【讨论】:
这行不通,因为它会破坏 json 格式。 @OrDuan 我同意,但最初的问题包括“lines=True”,这意味着 json 的格式设置为每行都是不同的 json 对象。如果是这种情况,上述解决方案应该可以工作。 @NathanH 感谢您这么快回复我。我尝试了您的建议并收到一条错误消息。我添加了我运行的代码和错误消息作为对原始帖子的更新。你知道问题可能是什么吗?还使用您的建议,我可以读取一组记录而不是整个文件吗?是这个主意吗? @user3476463 你能发布一个json结构的例子吗?这在试图解决这个问题时会有所帮助。另外,你能不能直接打开json文件,把一些对象复制到一个新文件中,然后处理这个文件? @NathanH 一旦我将默认编码设置为 utf-8,我就可以使用您的建议从 json 文件中导入一些记录,谢谢!如果我想发布 json 数据的样本,我该如何打开它并获取一些?我之前尝试将文件放入文本编辑器,但它太大了,它只是锁定了文本编辑器。有没有办法在python中做到这一点?【参考方案3】:我同意@Nathan H 的提议。但确切的点可能在于并行化。
import pandas as pd
buf = ''
buf_lst = []
df_lst = []
chunk_size = 1000
with open('dataset/review.json','r') as f:
lines = f.readlines()
buf_lst += [ ''.join(lines[x:x+chunk_size]) for x in range(0,len(lines), chunk_size)]
def f(buf):
return pd.read_json( buf,lines=True)
#### single-thread
df_lst = map( f, buf_lst)
#### multi-thread
import multiprocessing as mp
pool = mp.Pool(4)
df_lst = pool.map( f, buf_lst)
pool.join()
pool.close()
但是,我还不确定如何组合 pandas 数据框。
【讨论】:
我希望你已经知道了,但是 pandas.concat(list_of_frames) 是你想要组合它们的东西以上是关于加快将 json 数据加载到数据框中的主要内容,如果未能解决你的问题,请参考以下文章