web-dev-qa-db-ja.com

複数のJSONレコードをPandasデータフレームに読み込む

マルチレコードのJSONファイル(各行はJSON dict)をpandasデータフレームに読み込むメモリ効率の良い方法があるかどうかを知りたい。潜在的に非常に多数のレコードに必要ですが、使用例はHadoop Pig JSonStorage関数からの出力を処理することです。

import json
import pandas as pd

test='''{"a":1,"b":2}
{"a":3,"b":4}'''
#df=pd.read_json(test,orient='records') doesn't work, expects []

l=[ json.loads(l) for l in test.splitlines()]
df=pd.DataFrame(l)
41
seanv507

注:行区切りのjsonが read_json (0.19.0以降):

In [31]: pd.read_json('{"a":1,"b":2}\n{"a":3,"b":4}', lines=True)
Out[31]:
   a  b
0  1  2
1  3  4

または、json文字列ではなくファイル/ファイルパスを使用します。

pd.read_json(json_file, lines=True)

DataFrameのサイズに依存しますが、これは高速ですが、別のオプションはstr.join複数行の「JSON」(注:有効なjsonではありません)を有効なjsonに粉砕し、read_jsonを使用します。

In [11]: '[%s]' % ','.join(test.splitlines())
Out[11]: '[{"a":1,"b":2},{"a":3,"b":4}]'

この小さな例では、これは遅くなります。100程度の場合、それはより大きくなると同様の有意なゲインになります...

In [21]: %timeit pd.read_json('[%s]' % ','.join(test.splitlines()))
1000 loops, best of 3: 977 µs per loop

In [22]: %timeit l=[ json.loads(l) for l in test.splitlines()]; df = pd.DataFrame(l)
1000 loops, best of 3: 282 µs per loop

In [23]: test_100 = '\n'.join([test] * 100)

In [24]: %timeit pd.read_json('[%s]' % ','.join(test_100.splitlines()))
1000 loops, best of 3: 1.25 ms per loop

In [25]: %timeit l = [json.loads(l) for l in test_100.splitlines()]; df = pd.DataFrame(l)
1000 loops, best of 3: 1.25 ms per loop

In [26]: test_1000 = '\n'.join([test] * 1000)

In [27]: %timeit l = [json.loads(l) for l in test_1000.splitlines()]; df = pd.DataFrame(l)
100 loops, best of 3: 9.78 ms per loop

In [28]: %timeit pd.read_json('[%s]' % ','.join(test_1000.splitlines()))
100 loops, best of 3: 3.36 ms per loop

注:その時間の結合は驚くほど高速です

45
Andy Hayden

メモリを節約しようとしている場合、一度に1行ずつファイルを読み取ると、メモリ効率が大幅に向上します。

with open('test.json') as f:
    data = pd.DataFrame(json.loads(line) for line in f)

また、import simplejson as jsonsimplejsonに含まれるコンパイル済みC拡張は、pure-Python jsonモジュールよりもはるかに高速です。

27
Doctor J

Pandas 0.19、read_jsonには 行区切りJSON のネイティブサポートがあります。

pd.read_json(jsonfile, lines=True)
14
Doctor J

++++++++ Update ++++++++++++++

V0.19の時点で、Pandasはこれをネイティブにサポートしています( https://github.com/pandas-dev/pandas/pull/13351 を参照)。実行するだけです:

_df=pd.read_json('test.json', lines=True)
_

++++++++古い回答++++++++++

既存の答えは良いですが、少し多様な場合、pythonのようにpd.read_json()ができるように、簡単な前処理ステップを必要とする目標を達成する別の方法がありますデータを消費します。

  • Jqのインストール https://stedolan.github.io/jq/
  • _cat test.json | jq -c --Slurp . > valid_test.json_で有効なjsonファイルを作成します
  • df=pd.read_json('valid_test.json')を使用してデータフレームを作成します

Ipythonノートブックでは、セルインターフェイスから直接シェルコマンドを実行できます。

_!cat test.json | jq -c --Slurp . > valid_test.json
df=pd.read_json('valid_test.json')
_
2
Bob Baxley