pandasの入出力について
概要
- pandasの各種入出力の説明
- 各種トラブルシューティングについて
CSV
- 概要
- 文字列が含まれるとパースに失敗する事がありあまり安全なファイルのやり取りの方法ではない
- 多くのファイルで採用されている
- エスケープの方法に方言があり、出力後正しくパースできないこともある
- 型情報がない
read_csv
- 引数
error_bad_lines
- パースに失敗した行をスキップする
usecols
- 使用するcolを指定する
- 無駄なcolを読み込まないので高速化する
skiprows
- 先頭の行がメタ情報などの時、
skiprows=N
して読み飛ばす - 例えば、Google Adsの場合、先頭二行はメタ情報なので、
skiprows=2
する
- 先頭の行がメタ情報などの時、
encoding
- csvファイルの文字コードの指定
dtype
- 指定したカラムを特定のデータ・タイプで予約して読み込む
- 0から始まる文字があったりすると消えたりするのでそれを防ぐ役割がある
- e.g.
dtype={'foobar': 'str'}
engine
- csvをパースするのにどのエンジンを使うか
- jsonで日本語を含む場合、デフォルトの
engine="c"
だとたまにエラーになり、engine="python"
の設定が必要
パースに失敗する時
- engineをpythonに変える
- 前のパイプラインの処理の出力をcsvからpickleに変える
- error_bad_linesをFalseに設定する
既存のファイルに追記する
- ファイルベースで値を後でaggregationしたいときなどに使える
df.to_csv("target.csv", index=None, header=None, mode="a")
標準入出力から出力をcsvとして読み取る
- セパレータとして正規表現を用いることができる
raw = os.popen('''any command''').read().strip()
df = pd.read_csv(io.StringIO(raw), sep=r"\s{1,}", engine="python")
EXCEL
- 概要
- エクセルで読める形式で書き込む方法
- windowsを使用しているユーザにわたすときに最適(csvだと文字コードの関係で文字化けする)
- 別途モジュールの
xlsxwriter
が必要
excelのシート名を取得する
pd.ExcelFile
を利用する
sheet_names = pd.ExcelFile("path.xlsx").sheet_names
print(sheet_names)
excelのシート名を指定して読み込む
df = pd.read_excel("path.xlsx", "sheet_name")
to_excel
with pd.ExcelWriter('<output-name>.xlsx', engine="xlsxwriter") as writer:
df.to_excel(writer, sheet_name="sheet-name")
JSON
- 概要
- jsonフォーマットで保存する
- jsonlフォーマットで保存する
- jsonlフォーマットとは各行が一つのjsonオブジェクトになっている構造のこと
- json linesという規格
レコードごとにカラム名付きのobjectにする
df.to_json(orient="records", force_ascii=False)
# [{'c0': v00, 'c1': v01, ...}, {'c0': v10, 'c1': v11, ...}]
jsonlフォーマットで出力する
df.to_json("<output-filename>.jsonl", orient="records", lines=True, force_ascii=False)
jsonlフォーマットを読み込む
# BQで使うような複数行のjsonでなるデータの読み込み
df = pd.read_json("log.json.gz", compression="gzip", lines=True)
PICKLE
- 概要
- pickle形式で出力する
- csvで保存するのに比べて早い
- 複雑な文字列がデータフレームに入っていてもエラーが起きない
- 保存時に圧縮の拡張子をつけると自動で圧縮される
- e.g.
xz
,bz2
,gz
- e.g.
to_pickle
df.to_pickle('<output-name>.pkl')
read_pickle
- 圧縮を有効にすると遅い
PARQUET
- 概要
- 組木の意味
- 発音は
パーケ
SQLite
書込み
import pandas as pd
import sqlite3
data = {'column1': [1, 2, 3], 'column2': ['A', 'B', 'C']}
df = pd.DataFrame(data)
with sqlite3.connect('database.db') as conn:
# if_exists='replace'は、同名のテーブルが存在する場合に置き換える
# 他のオプションには 'fail', 'append'
df.to_sql('table_name', conn, if_exists='replace', index=False)
読込み
# データが書き込まれたことを確認するために、データベースから読み込んで表示
with sqlite3.connect('database.db') as conn:
df_loaded = pd.read_sql_query("SELECT * FROM table_name", conn)
display(df_loaded)
json
, pickle
, csv
どのフォーマットが最も早いのか
- 1000万件のツイートの保存で実験すると以下のようになる
- pickle
- 16sec
- csv
- 46sec
- json
- 46sec
- pickle
プログラム上のヒアドキュメントなどから直接csvとして解釈して読み込む
io.StringIO
を利用する
from io import StringIO
import pandas as pd
csv_string = """Spark,25000,50 Days,2000
Pandas,20000,35 Days,1000
Java,15000,,800
Python,15000,30 Days,500
PHP,18000,30 Days,800"""
df = pd.read_csv(StringIO(csv_string), sep=",", header=None)