pandasではデフォルトでutf-8のcsvを読み込むことになっているために起こるエラー。
encoding:元ファイルの文字コードを指定するパターン
read_csvに対して、encoding='shift_jis'などのオプションを付与。
特にwindows環境下で作られたcsv(Excelで作成したものなど)は、shift_jisやcp932を指定することで解決する事がある。
参考:https://insilico-notebook.com/python-unicodedecodeerror/
(↑のサイトにはpythonが標準でサポートする日本語文字コードの一覧がある。)
本来はこれで解決するはずだが、解決しないことが多い。原因不明。
import pandas as pd
df = pd.read_csv('data.csv', encoding='shift_jis')
engine:エンコーディングをpythonで行う
read_csvに対して、engine="python"オプションを付与する方法。
https://punhundon-lifeshift.com/engine_python
import pandas as pd
df = pd.read_csv('data.csv', engine='python')
codecs(f, "ignore"):無視するパターン
fileopenにcodecsを使い、ignoreオプションを付けるパターン。
https://qiita.com/niwaringo/items/d2a30e04e08da8eaa643
どのようなファイル形式が来るか分からない中では、ignoreしてしまうのが手っ取り早い。
一方で、文字化けの原因を作る事にもなるので、推奨しづらい。
公式ドキュメント:https://docs.python.org/ja/3/library/codecs.html
import pandas as pd
import codecs
with codecs.open("path/to/file", "r", "shift_jis", "ignore") as file:
df = pd.read_csv('data.csv')
print(df)
codec.StreamRecorder:文字コードを変換する
code.StreamRecorderを使って文字コードを変換するパターン。
おそらく、この方法が最善。
https://dev.classmethod.jp/articles/python-encoding/
公式ドキュメント:https://docs.python.org/ja/3/library/codecs.html
StreamRecorderは引数でlookupメソッドから返されるCodecInfoを使うため、少し回りくどい書き方になっている。
サンプルでは、HttpRequestから受け取ったファイルストリームをShift_JISからutf-8へ変換している。
f = request.FILES['original_file'] #HttpRequestから受け取るファイルストリーム
codec_sjis = codecs.lookup("shift_jis")
codec_utf8 = codecs.lookup("utf-8")
f_utf8 = codecs.StreamRecoder(
f,
codec_utf8.encode, codec_sjis.decode,
codec_sjis.streamreader, codec_utf8.streamwriter,
)
data_frame = pd.read_csv(f_utf8)
元のファイルを何らかの方法でutf-8に変換
1回限りのread_csvなら許容だが、繰り返し使える方法ではない。
■文字コードを判別する方法
CSVの文字コードが予め分かっていない場合に、それを判別するには、chardetライブラリを使う。
https://blog.imind.jp/entry/2019/08/24/143939