UnicodeDecodeError で CSV が読めない原因は? pandas の文字コード問題を解決する
utf-8 で読めない CSV を pandas で正しく扱う方法
pandas で CSV を読み込もうとしたとき、 UnicodeDecodeError が出て止まることがあります。 解析や前処理をしているとかなり頻繁に遭遇するエラーですが、 原因は単純であることが多いです。
先に結論を書くと、このエラーは 「その CSV の実際の文字コード」と「pandas が読もうとしている文字コード」が一致していない ときに起きます。 Python 公式でも UnicodeDecodeError は デコード時に起きる Unicode 関連のエラー と説明されています。 (出典: Python Documentation – Built-in Exceptions )
pandas の read_csv() には encoding と encoding_errors という引数があり、 文字コードの指定やエラー時の扱いを変えられます。 公式ドキュメントでは encoding のデフォルトは 'utf-8'、 encoding_errors のデフォルトは 'strict' と案内されています。 (出典: pandas Documentation – pandas.read_csv )
このエラーが起きる一番多い原因
もっとも多いのは、 CSV が UTF-8 ではないのに、UTF-8 として読もうとしているケース です。 pandas の read_csv() はデフォルトで encoding='utf-8' を使うため、 実際のファイルが cp932、 shift_jis、 latin-1 など別の文字コードで保存されていると、 デコードに失敗して UnicodeDecodeError が出ます。 (出典: pandas Documentation – pandas.read_csv )
日本語の実務データでは、 Excel で保存した CSV や古い業務システムから出た CSV が UTF-8 ではなく cp932 や shift_jis になっていることがかなり多いです。 そのため、まず疑うべきはコードのバグではなく ファイルの文字コード です。
まず試すべき対処法
いちばん簡単な対処は、 encoding を明示して読み直すことです。
import pandas as pd
df = pd.read_csv("data.csv", encoding="cp932")
あるいは、UTF-8 だが BOM 付きのファイルなら、 次のように utf-8-sig を指定すると安定することがあります。
import pandas as pd
df = pd.read_csv("data.csv", encoding="utf-8-sig")
pandas 公式でも read_csv() は encoding を受け取れると明記されています。 つまり、 文字コードの食い違いは、まず encoding を合わせることで解決する のが基本です。 (出典: pandas Documentation – pandas.read_csv )
よく使う文字コードの候補
日本語 CSV でよく試される候補は次のあたりです。
utf-8utf-8-sigcp932shift_jislatin-1(内容確認用の一時回避として)
実務では、 まず UTF-8 系を試し、だめなら cp932 を試す という順番が現実的です。 とくに Windows 由来の日本語 CSV は cp932 で通ることが多いです。
エラーを無理に回避する方法はあるか
pandas の read_csv() には encoding_errors という引数もあります。 公式ドキュメントではデフォルトが 'strict' で、 エラー時の扱いを変えられると案内されています。 (出典: pandas Documentation – pandas.read_csv )
たとえば、どうしても中身をざっと確認したいだけなら、 次のようにして強引に読むこともできます。
import pandas as pd
df = pd.read_csv("data.csv", encoding="utf-8", encoding_errors="ignore")
ただしこの方法は、 読めなかった文字を捨てる可能性がある ため、 本番の解析では慎重に使うべきです。 文字化けや列ズレの原因を隠してしまうことがあるからです。
それでも読めないときに見るべきポイント
文字コードだけでなく、 実際には次のような要因が重なっていることもあります。
- CSV の一部だけ別の文字コードで混ざっている
- ファイル先頭に BOM が入っている
- 拡張子は .csv だが中身の区切りがカンマではない
- 壊れた行や列数のずれが混じっている
pandas の read_csv() には on_bad_lines があり、 不正な行に遭遇したとき 'error'、 'warn'、 'skip' を選べます。 公式ドキュメントでも、 bad line に対してどう振る舞うかを切り替えられると説明されています。 (出典: pandas Documentation – pandas.read_csv )
そのため、 文字コード問題だと思っていたものが、 実際には 壊れた行や区切り文字の問題だった ということもあります。 文字コードを変えても読めない場合は、 こちらも疑うべきです。
実務でおすすめの確認手順
CSV が読めないときは、次の順番で確認すると効率がいいです。
- まず
utf-8で読む - だめなら
utf-8-sigを試す - 次に
cp932を試す - それでもだめなら
shift_jisを試す - 必要なら
encoding_errors="ignore"で中身だけ確認する - 最後に
on_bad_linesや区切り文字の問題を確認する
たとえば、次のような形です。
import pandas as pd
try:
df = pd.read_csv("data.csv", encoding="utf-8")
except UnicodeDecodeError:
df = pd.read_csv("data.csv", encoding="cp932")
本当はファイルの文字コードを事前に確認できるのが理想ですが、 実務ではまずこの程度の切り分けで十分役立つことが多いです。
よくある誤解
このエラーが出ると、 「pandas が壊れている」 「CSV の形式が完全におかしい」 と考えてしまいがちです。 ただ、実際には ファイル自体は正常で、読み方だけが合っていない ケースがかなり多いです。
逆に、 encoding_errors="ignore" で読めたから解決した、 と判断するのも危険です。 その時点では エラーを無視しているだけ で、データ品質の問題は残っている可能性があります。
まとめ
UnicodeDecodeError で CSV が読めないときは、 まず CSV の文字コードと、pandas の encoding 指定が一致しているか を確認するべきです。 Python 公式では UnicodeDecodeError はデコード時の Unicode エラーであり、 pandas 公式では read_csv() に encoding と encoding_errors が用意されています。 つまり、この問題は多くの場合、 pandas の不具合ではなく文字コード指定の問題 です。 (出典: Python Documentation – Built-in Exceptions / pandas Documentation – pandas.read_csv )
実務上は、 utf-8、 utf-8-sig、 cp932 の順に試し、 それでもだめなら on_bad_lines や区切り文字の問題を疑う、 という流れがいちばん現実的です。

コメント