K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

全角・半角のゆれを正規化する

01.7.1

全角・半角のゆれを正規化する

最終更新 2020-01-29 読了時間 2 分
まとめ
「ABC 株式会社―営業部」のように全角英字・全角スペース・ダッシュ類が混ざった入力を、unicodedata.normalize("NFKC", text) で「ABC 株式会社」のような半角英数と全角カナに揃えます。NFKC は「㈱」を「(株)」、「①」を「1」に展開してくれますが、長音「ー」やダッシュ「―」、曲がった引用符「’」「”」には手を付けないので、str.maketrans で作った TRANSLATION_TABLE で補います。検索やグルーピングの前に通す最初の正規化で、同じ会社名が全角・半角の違いで 2 行に割れるのを防ぎます。

直感 #

日本語の入力フォームから集めたデータでは、同じ「ABC株式会社 営業部」でも、人によって「ABC」と全角で打ったり、区切りに「―」「-」「-」のどれかを使ったり、スペースを全角で入れたりします。groupby や完全一致の検索は 1 文字でも違えば別物と見るので、先に 1 つの表記へ寄せます。Unicode には「見た目が違うだけの互換文字を標準の文字に戻す」NFKC という正規化形式があり、全角英数字→半角、半角カナ→全角カナ、「㈱」→「(株)」などをまとめて処理してくれます。ただし「ー」と「-」のように Unicode 上は別の意味を持つ文字は NFKC では統一されないため、業務ルールとして決めた置換テーブルを後ろに付けます。

Python で正規化する #

次のコードは NFKC では揃わない 5 文字の置換テーブルを用意し、normalize_ja が NFKC → テーブル置換 → 空白の整理の順で文字列を返します。3 件のサンプルには NFKC だけで揃うもの、テーブルで揃うもの、どちらでも揃わない記号を含むものを混ぜています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
import unicodedata

TRANSLATION_TABLE = str.maketrans(
    {
        "ー": "-",  # 長音記号をハイフンへ統一
        "~": "~",
        "―": "-",
        "’": "'",
        "”": '"',
    }
)

def normalize_ja(text: str) -> str:
    if text is None:
        return ""
    text = unicodedata.normalize("NFKC", text)
    text = text.translate(TRANSLATION_TABLE)
    text = text.replace("\u3000", " ").replace(" ", " ")  # 全角スペース
    while "  " in text:
        text = text.replace("  ", " ")
    return text.strip()

samples = [
    "ABC 株式会社―営業部",
    "abc㈱‐営業部",
    "ABC−営業部",
]

for s in samples:
    print(normalize_ja(s))

実行結果の読み方 #

1 件目「ABC 株式会社―営業部」は、全角英字と全角スペースが NFKC で、「―」がテーブルで直り、「ABC 株式会社-営業部」になります。2 件目は「㈱」が「(株)」に展開されましたが「‐」(U+2010) は残り、3 件目の「−」(U+2212) も残っているので、3 件は同じ部署でも 3 通りの文字列のままです。実データで value_counts() を取り、残った記号を TRANSLATION_TABLE に 1 つずつ追加していくのが、この関数を育てる手順になります。

使いどころと落とし穴 #

全角スペースは strip() の既定では落ちない("  ABC".strip() は全角スペースを残す)ので、NFKC かテーブルで明示的に半角へ統一してから strip() します。「①」や「㈱」は NFKC で「1」「(株)」に展開されます。日付や数値の列にも「2024」のような全角数字が混ざることがあり、pd.to_numeric の前に normalize_ja を噛ませると変換エラーが減ります。ブランド名や製品コードでハイフンの種類が意味を持つ場合は、「ー」→「-」の置換が情報を壊すので、列ごとに別のテーブルを使い分けてください。