01.9.2
read_csvで列数が合わずParserErrorになる
ParserError: Expected 5 fields in line 12, saw 7 は、pandas が 1 行目から「1 行は 5 列」と決めたのに、12 行目でカンマが 6 個あって 7 列に見えた、という報告です。原因は区切り文字が実はセミコロンやタブだった(sep=";", sep="\t" で直す)か、"東京, 渋谷" のようにセルの中にカンマがあるのに引用符で守られていなかった(quotechar と escapechar で直す)かのどちらかがほとんどです。それでも崩れた行が残るときは engine="python" と on_bad_lines="warn" で、どの行が壊れているかを警告として出しながら読み進めます。このページでは sales.csv・survey.csv・messy.csv の 3 つの例で、メッセージの数字から原因を特定する手順を示します。直感 #
read_csv は 1 行目を区切り文字で割って「この表は 5 列」と決め、以降の行も同じ数に割れることを期待します。; 区切りのファイルを , で割ると全行が 1 列になり、逆にセルの中に , が混ざった行だけ列数が増えます。エラーメッセージの Expected 5 fields in line 12, saw 7 は「期待 5、実際 7、場所は 12 行目」をそのまま教えてくれているので、sed -n 12p sales.csv でその行を見れば、余分なカンマがどこにあるかが分かります。
pandas.read_csv() で次のようなエラーに遭遇したことはありませんか?
pandas.errors.ParserError: Error tokenizing data. C error: Expected 5 fields in line 12, saw 7
あるいは
pandas.errors.ParserError: ',' expected after '"'
といったメッセージです。前者は列数のずれ、後者は " で始まったセルが閉じないまま次の区切りに到達したことを表し、どちらも 区切り文字や引用符の扱いが想定と違う ときに起こります。典型的な原因は 3 つあり、CSV が実はタブ区切り(\t)やセミコロン区切り(;)だった場合、1 つのセルに "東京, 渋谷" のようなカンマが含まれていて引用符で囲まれていなかった場合、そしてダブルクオートが途中で途切れていてエスケープ文字も定義されていない場合です。
解決法 1: 区切り文字を正しく指定する #
ファイルの先頭数行を head -n 3 sales.csv やメモ帳で確認し、カンマ以外で区切られていたら sep でその文字を伝えます。
| |
解決法 2: 引用符とエスケープを合わせる #
Excel から書き出した CSV では セル内のカンマ や 改行 が混入していることがあります。セルを囲む文字が " ではなく ' だったり、\" のようにバックスラッシュでエスケープされていたりする場合は、その約束を quotechar と escapechar で伝えます。
| |
解決法 3: Python エンジンで柔軟に解析する #
標準の C エンジンは速い代わりに、複数文字の区切りや不規則な引用符を扱えません。engine="python" へ切り替え、on_bad_lines="warn" で崩れた行を警告しながら読み飛ばすと、どの行が壊れているかを記録しつつ残りを DataFrame にできます。
| |
on_bad_lines="skip"にすると崩れた行を無視できます。
データ損失を防ぎたい場合はwarnにしてログだけ取り、後で該当行を手動で修正しましょう。
使いどころと落とし穴 #
直す前に必ず head -n 3 で区切り文字を目で確かめ、sep を設定したかを最初に見ます。セル内にカンマや改行がある列は " で囲まれている必要があり、Excel で書き出すときに「CSV UTF-8(カンマ区切り)」以外を選ぶと ; 区切りや引用符なしのファイルになることがあります。on_bad_lines="warn" で読み飛ばした行数は len(df) と元ファイルの行数の差で確認し、差が数行を超えるなら sep か quotechar の見立てを疑ってください。
参考 #
sep・quotechar・escapechar・on_bad_lines の仕様は pandas.read_csv — pandas documentation に、引用符とエスケープの元になっている方言の定義は CSV File Reading and Writing — Python documentation にあります。