read_csvのエラー処理について
pandasのread_csvについて、調べても中々解決しなくてイライラしてたけどやっと解決。
無駄に半日以上使ってしまった。
をみて解決を図ってたんだけど、エラーハンドリング用にon_bad_linesというパラメータがあって
トラップ用の関数か、文字列で指定しろって項目があるんだけどこれが曲者で色々はまった。
一つ目。
ヘッダのカラム数と一致しなくても、少ない分にはエラー扱いされない。
警告もでない。
公式の説明にもある通り、カラム数が少なくてもトラップされない(´;ω;`)ウッ…
カンマの数とかタブの数とかは数えてくれないようだ。
二つ目。
エラー行と認識されるのは、カラム数がヘッダで定義しているものより多い場合に悪い行として認識されるらしい。
on_bad_linesはエンジンタイプが「python」のみの時に機能するので他のものが指定されていると注意。
三つ目。
on_bad_linesは関数で受け取ることもできるんだけど、これが全く使えなくて検知した行のデータのみが渡される。
ここが一番厄介だった。
例えば、関数ではなく「warn」とか指定してエラーメッセージを標準エラー出力でだすとキチンと欲しい情報、即ち
何行目の何々でエラーになったよっ的なメッセージがプリントされる。
ええ、そうでしょうとも。
その情報が欲しいんだよ、ワトソン君。
でもね、関数で受け取るとただのエラーが発生した行データがリストで渡されてくるだけ。
ドキュメントにもそう書いてあるし、仕様なんだろうけどさ。
鈴木雅之の「違う、そうじゃない」が頭の中でずっとリフレインするよ(#^ω^)
なんで標準出力のデータをそのまま受け取ることができないのか、みたいな?
エラー行のデータをリストでもらってどうしろと?
検索できないやん・・・。
どうやったらうまく、取得できる方法はないか色々試した結果、こうなりました。
import io
import contextlib
~
~
std_error = io.StringIO()
with contextlib.redirect_stderr(std_error):
# get_chunkの場合も同じ
df = pd.read_csv(file, on_bad_lines="warn", engine='python')
if( std_error.getvalue() ):
# ゲットだぜ!
error_msg = str(std_error.getvalue())
# 後は煮るなり焼くなり
間違えている場合もあるのであしからず。