UnicodeDecodeError で CSV が読めない原因は? pandas の文字コード問題を解決する

python

UnicodeDecodeError で CSV が読めない原因は? pandas の文字コード問題を解決する

utf-8 で読めない CSV を pandas で正しく扱う方法

pandas で CSV を読み込もうとしたとき、 UnicodeDecodeError が出て止まることがあります。 解析や前処理をしているとかなり頻繁に遭遇するエラーですが、 原因は単純であることが多いです。

先に結論を書くと、このエラーは 「その CSV の実際の文字コード」と「pandas が読もうとしている文字コード」が一致していない ときに起きます。 Python 公式でも UnicodeDecodeErrorデコード時に起きる Unicode 関連のエラー と説明されています。 (出典: Python Documentation – Built-in Exceptions

pandas の read_csv() には encodingencoding_errors という引数があり、 文字コードの指定やエラー時の扱いを変えられます。 公式ドキュメントでは encoding のデフォルトは 'utf-8'encoding_errors のデフォルトは 'strict' と案内されています。 (出典: pandas Documentation – pandas.read_csv

このエラーが起きる一番多い原因

もっとも多いのは、 CSV が UTF-8 ではないのに、UTF-8 として読もうとしているケース です。 pandas の read_csv() はデフォルトで encoding='utf-8' を使うため、 実際のファイルが cp932shift_jislatin-1 など別の文字コードで保存されていると、 デコードに失敗して UnicodeDecodeError が出ます。 (出典: pandas Documentation – pandas.read_csv

日本語の実務データでは、 Excel で保存した CSV や古い業務システムから出た CSV が UTF-8 ではなく cp932shift_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-8
  • utf-8-sig
  • cp932
  • shift_jis
  • latin-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 が読めないときは、次の順番で確認すると効率がいいです。

  1. まず utf-8 で読む
  2. だめなら utf-8-sig を試す
  3. 次に cp932 を試す
  4. それでもだめなら shift_jis を試す
  5. 必要なら encoding_errors="ignore" で中身だけ確認する
  6. 最後に 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()encodingencoding_errors が用意されています。 つまり、この問題は多くの場合、 pandas の不具合ではなく文字コード指定の問題 です。 (出典: Python Documentation – Built-in Exceptions / pandas Documentation – pandas.read_csv

実務上は、 utf-8utf-8-sigcp932 の順に試し、 それでもだめなら on_bad_lines や区切り文字の問題を疑う、 という流れがいちばん現実的です。

参考リンク

コメント

タイトルとURLをコピーしました