pandas.DataFrameをJSON文字列・ファイルに変換・保存(to_json)
pandas.DataFrame
のメソッドto_json()
を使うと、pandas.DataFrame
をJSON形式の文字列(str
型)に変換したり、JSON形式のファイルとして出力(保存)したりできる。
ここでは以下の内容について説明する。そのほかの引数については上記の公式ドキュメントを参照。
pandas.DataFrame.to_json()
の基本的な使い方- JSON形式の文字列に変換
- JSON形式のファイルとして出力(保存)
- ファイル圧縮: 引数
compression
- ファイル圧縮: 引数
- 形式を指定: 引数
orient
split
records
JSON Lines
(.jsonl
)
index
columns
(デフォルト)values
table
- 全角文字(日本語)などのUnicodeエスケープ: 引数
force_ascii
JSONファイルの読み込みはpandas.read_json()
。
pandas.DataFrame
を辞書(dict
型)に変換したい場合はto_dict()
メソッドを使う。
そのほかpandasでのCSVファイルやExcelファイルの読み書き(入出力)については以下の記事を参照。
- 関連記事: pandasでcsv/tsvファイル読み込み(read_csv, read_table)
- 関連記事: pandasでcsvファイルの書き出し・追記(to_csv)
- 関連記事: pandasでExcelファイル(xlsx, xls)の読み込み(read_excel)
- 関連記事: pandasでExcelファイル(xlsx, xls)の書き込み(to_excel)
また、pandasではなく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形式の文字列に変換
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.DataFrame
の行ラベルindex
、列ラベルcolumns
、値values
をどのようにJSONとして出力するかを指定できる。
ここでは、json.loads()
で出力文字列を辞書に変換しpprint()
で見やすく表示した結果も合わせて示す。
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(デフォルト)
{column -> {index -> value}}
引数orient
を省略した場合(デフォルト)はこの形式。
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'>