加速将json数据加载到数据帧中

时间:2017-10-25 19:30:46

标签: python json pandas

我正在尝试使用下面的代码将大量嵌套的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)

3 个答案:

答案 0 :(得分:1)

如果您的文件中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)

答案 1 :(得分:0)

加速这一行将具有挑战性,因为它已经超级优化。

如前所述,我首先会检查您是否可以从提供商那里获得更少的行/数据。

如果您之前可以处理数据,我建议之前将其转换为JSON(甚至尝试不同的解析器,它们对每个数据集结构的性能更改),而不是只保存您需要的数据,并使用此输出调用熊猫方法

Here你可以找到一些json解析器的基准测试,请记住你应该对你的数据进行测试,这篇文章是从2015年开始的。

答案 2 :(得分:0)

我同意@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数据帧。