note.nkmk.me

pandas.DataFrameをJSON文字列・ファイルに変換・保存(to_json)

Date: 2018-05-14 / tags: Python, pandas, JSON

pandas.DataFrameのメソッドto_json()を使うと、pandas.DataFrameをJSON形式の文字列(str型)に変換したり、JSON形式のファイルとして出力(保存)したりできる。

pandas.DataFrameを辞書(dict型)に変換したい場合はto_dict()メソッドを使う。以下の記事を参照。

また、Python標準ライブラリのjsonモジュールで辞書を整形してJSON形式のファイルや文字列に出力する方法は以下の記事を参照。

ここでは、例として以下のpandas.DataFrameを作成する。

import pandas as pd
import pprint
import json

df = pd.DataFrame({'col1': [1, 2, 3], 'col2': ['a', 'x', 'あ']},
                  index=['row1', 'row2', 'row3'])

print(df)
#       col1 col2
# row1     1    a
# row2     2    x
# row3     3    あ

pprintとjsonは出力を見やすくするため、および、確認のためにインポートしている。処理自体には必要ない。

以下の内容について説明する。そのほかの引数については上記の公式ドキュメントを参照。

  • pandas.DataFrame.to_json()の基本的な使い方
    • JSON形式の文字列に変換
    • JSON形式のファイルとして出力(保存)
      • ファイル圧縮: 引数compression
  • 形式を指定: 引数orient
  • 全角文字(日本語)などのUnicodeエスケープ: 引数force_ascii
  • その他の引数

jsonファイルの読み込みは以下の記事を参照。

そのほかpandasでのcsvファイル、Escelファイルの読み書き(入出力)については以下の記事を参照。

スポンサーリンク

pandas.DataFrame.to_jsonの基本的な使い方

JSON形式の文字列に変換

pandas.DataFrameからto_json()メソッドを呼び出すと、デフォルトでは以下のようにJSON形式の文字列(str型)に変換される。

print(df.to_json())
# {"col1":{"row1":1,"row2":2,"row3":3},"col2":{"row1":"a","row2":"x","row3":"\u3042"}}

print(type(df.to_json()))
# <class 'str'>

全角文字などの非ascii文字はUnicodeエスケープされる。引数force_ascii=FalseとするとUnicodeエスケープされない。後述。

Unicodeエスケープについては以下の記事を参照。

JSON形式のファイルとして出力(保存)

第一引数にパスを指定するとファイルとして保存される。パスを指定しない場合に出力される文字列がそのままファイルとして書き込まれる。

path = 'data/src/sample_from_pandas_columns.json'

df.to_json(path)

テキストファイルとして読み込み中身を確認。

with open(path) as f:
    s = f.read()
    print(s)
    print(type(s))
# {"col1":{"row1":1,"row2":2,"row3":3},"col2":{"row1":"a","row2":"x","row3":"\u3042"}}
# <class 'str'>

open()の引数encoding='unicode-escape'とするとUnicodeエスケープシーケンス\uXXXXは対応する文字に変換される。

with open(path, encoding='unicode-escape') as f:
    s = f.read()
    print(s)
    print(type(s))
# {"col1":{"row1":1,"row2":2,"row3":3},"col2":{"row1":"a","row2":"x","row3":"あ"}}
# <class 'str'>

標準ライブラリjsonモジュールのjson.load()関数で辞書として読み込み。この場合、特に何も設定しなくてもUnicodeエスケープシーケンス\uXXXXは対応する文字に変換される。

with open(path) as f:
    d = json.load(f)
    print(d)
    print(type(d))
# {'col1': {'row1': 1, 'row2': 2, 'row3': 3}, 'col2': {'row1': 'a', 'row2': 'x', 'row3': 'あ'}}
# <class 'dict'>

JSONファイルをpandas.DataFrameとして読み込む場合はpandas.read_json()関数を使う。この場合も、Unicodeエスケープシーケンス\uXXXXは対応する文字に変換される。

df_read = pd.read_json(path)
print(df_read)
#       col1 col2
# row1     1    a
# row2     2    x
# row3     3    あ

ファイル圧縮: 引数compression

pandasのバージョン0.21.0から追加された引数compressionを指定すると、ファイル出力時に圧縮することが可能。

'gzip', 'bz2', 'xz'のいずれかを指定する。

df.to_json('data/src/sample_from_pandas_columns.gz', compression='gzip')

形式を指定: 引数orient

引数orientによって、pandas.DataFarmeの行ラベルindex、列ラベルcolumns、値valuesをどのようにJSONとして出力するかを指定できる。

ここでは、json.loads()で出力文字列を辞書に変換しpprint()で見やすく表示した結果も合わせて示す。

json.loads()の詳細については以下の記事を参照。

split

{index -> [index], columns -> [columns], data -> [values]}

print(df.to_json(orient='split'))
# {"columns":["col1","col2"],"index":["row1","row2","row3"],"data":[[1,"a"],[2,"x"],[3,"\u3042"]]}

pprint.pprint(json.loads(df.to_json(orient='split')))
# {'columns': ['col1', 'col2'],
#  'data': [[1, 'a'], [2, 'x'], [3, 'あ']],
#  'index': ['row1', 'row2', 'row3']}

records

[{column -> value}, ... , {column -> value}]

print(df.to_json(orient='records'))
# [{"col1":1,"col2":"a"},{"col1":2,"col2":"x"},{"col1":3,"col2":"\u3042"}]

pprint.pprint(json.loads(df.to_json(orient='records')), width=40)
# [{'col1': 1, 'col2': 'a'},
#  {'col1': 2, 'col2': 'x'},
#  {'col1': 3, 'col2': 'あ'}]

JSON Lines(.jsonl)

引数orient='recordsの場合、引数lines=Trueとすると{column: value}ごとに改行された文字列となる。

print(df.to_json(orient='records', lines=True))
# {"col1":1,"col2":"a"}
# {"col1":2,"col2":"x"}
# {"col1":3,"col2":"\u3042"}

これにより、JSONが改行で区切られたJSON Lines(.jsonl)フォーマットの文字列やファイルを作成できる。

index

{index -> {column -> value}}

print(df.to_json(orient='index'))
# {"row1":{"col1":1,"col2":"a"},"row2":{"col1":2,"col2":"x"},"row3":{"col1":3,"col2":"\u3042"}}

pprint.pprint(json.loads(df.to_json(orient='index')))
# {'row1': {'col1': 1, 'col2': 'a'},
#  'row2': {'col1': 2, 'col2': 'x'},
#  'row3': {'col1': 3, 'col2': 'あ'}}

columns

引数orientを省略した場合(デフォルト)はこの形式。

{column -> {index -> value}}

print(df.to_json(orient='columns'))
# {"col1":{"row1":1,"row2":2,"row3":3},"col2":{"row1":"a","row2":"x","row3":"\u3042"}}

pprint.pprint(json.loads(df.to_json(orient='columns')))
# {'col1': {'row1': 1, 'row2': 2, 'row3': 3},
#  'col2': {'row1': 'a', 'row2': 'x', 'row3': 'あ'}}

values

print(df.to_json(orient='values'))
# [[1,"a"],[2,"x"],[3,"\u3042"]]

pprint.pprint(json.loads(df.to_json(orient='values')))
# [[1, 'a'], [2, 'x'], [3, 'あ']]

table

データの構造scheme情報をもつ形式。

print(df.to_json(orient='table'))
# {"schema": {"fields":[{"name":"index","type":"string"},{"name":"col1","type":"integer"},{"name":"col2","type":"string"}],"primaryKey":["index"],"pandas_version":"0.20.0"}, "data": [{"index":"row1","col1":1,"col2":"a"},{"index":"row2","col1":2,"col2":"x"},{"index":"row3","col1":3,"col2":"\u3042"}]}

pprint.pprint(json.loads(df.to_json(orient='table')))
# {'data': [{'col1': 1, 'col2': 'a', 'index': 'row1'},
#           {'col1': 2, 'col2': 'x', 'index': 'row2'},
#           {'col1': 3, 'col2': 'あ', 'index': 'row3'}],
#  'schema': {'fields': [{'name': 'index', 'type': 'string'},
#                        {'name': 'col1', 'type': 'integer'},
#                        {'name': 'col2', 'type': 'string'}],
#             'pandas_version': '0.20.0',
#             'primaryKey': ['index']}}

全角文字(日本語)などのUnicodeエスケープ指定: 引数force_ascii

引数force_ascii=Falseとすると、全角文字(日本語)などがUnicodeエスケープされずに出力される。

print(df.to_json(force_ascii=False))
# {"col1":{"row1":1,"row2":2,"row3":3},"col2":{"row1":"a","row2":"x","row3":"あ"}}

これまでの例のようにデフォルト(省略した場合)はforce_ascii=TrueでUnicodeエスケープされる。

上でも示したが、標準ライブラリjsonモジュールのjson.load(), json.loads()関数やpandas.read_json()関数でJSON形式のファイルや文字列を読み込む場合は、Unicodeエスケープされた文字も対応する文字に正しく変換される。

with open(path) as f:
    d = json.load(f)
    print(d)
    print(type(d))
# {'col1': {'row1': 1, 'row2': 2, 'row3': 3}, 'col2': {'row1': 'a', 'row2': 'x', 'row3': 'あ'}}
# <class 'dict'>

df_read = pd.read_json(path)
print(df_read)
#       col1 col2
# row1     1    a
# row2     2    x
# row3     3    あ

open()でテキストファイルとして読み込む場合は、引数encoding='unicode-escape'とするとUnicodeエスケープシーケンス\uXXXXは対応する文字に変換される。

with open(path) as f:
    s = f.read()
    print(s)
    print(type(s))
# {"col1":{"row1":1,"row2":2,"row3":3},"col2":{"row1":"a","row2":"x","row3":"\u3042"}}
# <class 'str'>

with open(path, encoding='unicode-escape') as f:
    s = f.read()
    print(s)
    print(type(s))
# {"col1":{"row1":1,"row2":2,"row3":3},"col2":{"row1":"a","row2":"x","row3":"あ"}}
# <class 'str'>
スポンサーリンク
シェア
このエントリーをはてなブックマークに追加

関連カテゴリー

関連記事