💭

【Python】日本語CSVが文字化けするときはcp932でエンコーディングしてみよう

2025/01/01に公開

はじめに

「Pythonでファイルを読み込んだら、日本語が文字化けしてしまった...😫」
「utf-8で読み込もうとしたけど、エラーが出てしまう...」
「丸数字(①)や株式会社(㈱)の記号が入っているファイルを読み込みたいんだけど、どうすればいいのかな?」

こんな経験をしたことはありませんか?
文字コードが原因となってその問題が発生するのですが、今回は解決方法の一つをご紹介します。

そもそも文字コード(エンコーディング)とは

私たちが普段見ている文字(「あ」や「A」など)は、実はコンピュータの中では数字の組み合わせとして保存されています。
この「文字と数字の対応規則」のことを「文字コード」や「エンコーディング」と呼びます。

例えば、同じ「あ」という文字でも、

  • UTF-8では「11100011 10000010 10000001」という数字で表現
  • cp932では「10000010 10000001」という数字で表現

というように、文字コードが違うと異なる数字で表現されます。
そのため、間違った文字コードでファイルを開くと、文字化けが発生してしまうのです。

文字コードの種類と特徴

主な文字コードには以下のようなものがあります。

  1. UTF-8
    現在のインターネットで最も広く使われている文字コードです。世界中のほぼすべての文字を表現できます。

  2. cp932
    Windowsの日本語版で標準的に使用される文字コードです。特にExcelで作成したファイルでよく使われます。

  3. Shift-JIS
    以前から日本で広く使われている文字コードです。cp932の元となった規格です。

cp932を使うメリット

ExcelやCSVファイルを読み込む際、以下のようにencoding='cp932'を指定することで、多くの問題を解決できます。

import pandas as pd

# CSVファイルを読み込む場合
df = pd.read_csv('data.csv', encoding='cp932')

# Excelファイルを保存する場合
df.to_excel('output.xlsx', encoding='cp932')

cp932を使用する主なメリットは以下の通りです。

  1. より広い文字セットをサポート
    cp932は、Shift_JISを拡張した文字コードです。
    Shift_JISでは表示できない機種依存文字(①、㈱、㍉など)も、cp932なら正しく表示できます。

  2. Excelとの互換性が高い
    Excelで作成したファイルは、多くの場合cp932でエンコードされています。
    そのため、cp932を指定することで、Excelファイルとの間でスムーズなデータのやり取りが可能になります。

  3. 古いシステムとの互換性
    レガシーシステムや古いデータとのやり取りが必要な場合、cp932を使用することで互換性の問題を解決できます。

実践的な使い方

文字コードの基礎を理解したところで、実際のプログラムでどのように対処するか、具体的な方法を説明していきます。
とりあえずcp932を試してうまくいけばそれでいいですが、手あたり次第に試すというのも一つの手です。

1. CSVファイルを確実に読み込む方法

まず、複数の文字コードを順番に試して、確実にファイルを読み込む方法をご紹介します。

def try_read_csv(file_path):
    """様々な文字コードを順番に試して、CSVファイルを読み込む関数"""
    # よく使われる文字コードを順番に試します
    encodings = ['cp932', 'utf-8', 'shift-jis', 'utf-16']
    
    for encoding in encodings:
        try:
            df = pd.read_csv(file_path, encoding=encoding)
            print(f"成功: {encoding}で読み込むことができました")
            return df
        except UnicodeDecodeError:
            print(f"{encoding}での読み込みに失敗しました。次の文字コードを試します。")
            continue
    
    print("すべての文字コードで読み込みに失敗しました。")
    return None

この関数は、以下のような手順で動作します。

  1. まず、よく使われる文字コードのリストを用意します。
  2. それぞれの文字コードで順番にファイルを開こうとします。
  3. 成功したら、その結果を返します。
  4. すべての文字コードで失敗した場合は、その旨を報告します。

2. 特殊な文字(機種依存文字)への対応

丸数字(①)や単位記号(㍉)などの特殊な文字が含まれているかどうかを確認し、適切に処理する方法を説明します。

import unicodedata

def check_special_chars(file_path):
    """ファイル内の特殊な文字を検出する関数"""
    try:
        # まずcp932で読み込んでみます
        df = pd.read_csv(file_path, encoding='cp932')
        
        # テキストが含まれる列のみを確認します
        for column in df.select_dtypes(include=['object']):
            for value in df[column].dropna():
                for char in str(value):
                    try:
                        # その文字の正式名称を取得します
                        name = unicodedata.name(char)
                        # 特殊な文字の可能性があるものを検出します
                        if 'COMPATIBILITY' in name or 'FULLWIDTH' in name:
                            print(f'特殊な文字を見つけました: {char} ({name})')
                    except ValueError:
                        print(f'システムが認識できない文字を見つけました: {char}')
        
        return df
    except UnicodeDecodeError as e:
        print(f"ファイルの読み込み時にエラーが発生しました: {str(e)}")
        return None

この関数は、以下のような場合に特に有用です。

  • データの中にどんな特殊な文字が含まれているか調べたい時。
  • 特殊な文字が原因でエラーが発生している可能性がある時。
  • データを別のシステムに渡す前に、問題が起きそうな文字がないか確認したい時。

3. 特殊な文字を安全に置き換える

特殊な文字が見つかった場合、それらを一般的な文字に置き換えて処理する方法をご紹介します。

def safe_read_csv(file_path):
    """特殊な文字を一般的な表記に置き換えてCSVファイルを読み込む関数"""
    # 特殊な文字と、それに対応する一般的な表記の対応表を作ります
    replacement_dict = {
        '①': '(1)',
        '②': '(2)',
        '③': '(3)',
        '㈱': '(株)',
        '㍉': 'ミリ',
        '㌢': 'センチ',
        '㌘': 'グラム',
        '㎜': 'mm',
        '㎝': 'cm',
        '㎞': 'km',
        '㎎': 'mg',
        '㎏': 'kg',
    }
    
    try:
        # まず、ファイルの内容をテキストとして読み込みます
        with open(file_path, 'r', encoding='cp932') as f:
            content = f.read()
            
        # 特殊な文字を一般的な表記に置き換えていきます
        for old, new in replacement_dict.items():
            content = content.replace(old, new)
            
        # 置き換えたテキストをpandasで読み込みます
        from io import StringIO
        df = pd.read_csv(StringIO(content))
        
        print("ファイルの読み込みと文字の置き換えが完了しました")
        return df
        
    except Exception as e:
        print(f"エラーが発生しました: {str(e)}")
        return None

この関数の特徴は以下の通りです。

  • 丸数字や単位記号などの特殊な文字を、一般的な表記に自動的に置き換えます。
  • 置き換え後のデータは、他のシステムでも問題なく使えます。
  • エラーが発生した場合は、その内容を分かりやすく表示します。

よくあるエラーとその対処法

ファイルの読み込み時によく遭遇するエラーと、その解決方法を説明します。

1. 文字コードに関するエラー(UnicodeDecodeError)

# エラーメッセージの例
UnicodeDecodeError: 'utf-8' codec can't decode byte 0x82 in position 0: invalid start byte

このエラーが表示された場合は、以下の手順を試してください。

  1. まずcp932での読み込みを試す。
df = pd.read_csv('ファイル名.csv', encoding='cp932')
  1. それでも解決しない場合は、ファイルの文字コードを確認する。

    • メモ帳でファイルを開き、「名前を付けて保存」で現在の文字コードを確認
    • 必要に応じて文字コードを変更して保存し直す
  2. Excelで開いて保存し直す。

    • ファイルをExcelで開く。
    • 「名前を付けて保存」で、新しくCSVとして保存する。
    • この際、ファイル名は変更しておくことをお勧めします。

2. データの区切りに関するエラー(DataError)

# エラーメッセージの例
pandas.errors.ParserError: Error tokenizing data

このエラーへの対処方法。

  1. ファイルの中身を確認する

    • メモ帳やVSCodeでファイルを開き、データの区切り文字(カンマやタブ)を確認
    • 欠損や余分な区切り文字がないかチェック
  2. 読み込み時にオプションを指定する。

df = pd.read_csv('ファイル名.csv', 
                 encoding='cp932',
                 sep=',',  # 区切り文字を明示的に指定
                 skiprows=1  # 必要に応じて先頭行をスキップ
                )

おまけ:Excelで文字化けが発生した場合の対処方法

CSVファイルをExcelで開いたときに文字化けが発生する場合、以下の手順で解決できます。

  1. メモ帳でCSVファイルを開く

    • メモ帳でファイルを開き、「ファイル」→「名前を付けて保存」を選択します
    • 「文字コード」という項目があるので、以下の順で試してみてください:
      • 「UTF-8」で保存して開いてみる
      • 「ANSI」で保存して開いてみる
      • 「Unicode(UTF-16LE)」で保存して開いてみる
  2. Excelでの開き方を変える

    • Excelで「データ」タブ→「テキストファイル」から開く
    • 文字コードを選択する画面が表示されるので、「65001: Unicode (UTF-8)」や「932: 日本語 (シフトJIS)」などを試してみる
  3. VSCodeなどの高機能エディタを使う

    • VSCodeは文字コードを自動判定する機能があり、より確実にファイルを開くことができます
    • 右下の文字コード表示をクリックすることで、様々な文字コードに変換できます

まとめ

これまでの内容を整理すると、以下の点に注意してファイルを処理することをお勧めします。

  1. ファイルの文字コードについて

    • 日本語を含むファイルでは、まずcp932での読み込みを試してみましょう
    • エラーが出た場合は、他の文字コード(UTF-8, Shift-JIS)も試してみましょう
    • エクセルで作成したファイルは、特にcp932を使うことが多いです
  2. 特殊な文字への対応

    • 丸数字(①)や単位記号(㍉)などの特殊な文字が含まれているかチェックしましょう
    • 必要に応じて、一般的な表記に置き換えることを検討しましょう
  3. エラーが発生した場合

    • エラーメッセージを確認し、適切な対処方法を選びましょう
    • メモ帳やVSCodeなどのテキストエディタを使って、ファイルの中身を確認することも有効です

このガイドが、みなさんのプログラミング作業のお役に立てば幸いです😊

Discussion