表記にばらつきのある文字列を置換で統一する方法です。
機械学習の前処理では、単語の正規化と言います。
表記ゆれとは
データを集計や分析するとき、ある単語が違った書き方をされることがあります。
具体的には、「データ」が「データー」と長音になったり、全角「データ」が半角「データ」になることです。
- 外来語 ・・・「コンピュータ」と「コンピューター」
- 文字の種類・・・「全角」と「半角」、「ひらがな」と「カタカナ」
- 送り仮名 ・・・「引っ越し」と「引越し」
- 漢字 ・・・「高橋」と「髙橋」
このように、同じ意味を表す単語の文字列がばらつくことを「表記ゆれ」と言います。
表記にばらつきがあると、正しく集計や抽出などができないので、表記を統一することが重要です。
文字列を指定して置換
表記を統一するには、文字列を指定して1つの単語にします。
文字列を別の文字列に置換するstr型のメソッドreplace()を使用します。
str.replace(old, new)
replaceメソッドは、第一引数oldで指定した文字列を、第二引数newで指定した文字列に置換します。
ひらがな「が」を、カタカナ「ケ」に置換します。
city_input = '鶴が島市'
city_replace = city_input.replace('が', 'ケ')
print(city_input, city_replace)
繰り返し処理で文字列を置換
replaceメソッドは、1つの文字列を指定して使用します。
複数の文字列を同じように置換するときは、for文で繰り返し処理をします。
「鶴ヶ島市」と「鶴が島市」を、「鶴ケ島市」に統一します。
配列city_inputから文字列を1つずつ取り出し、replaceで置換します。
特定の文字を置換
住所表記を「 鶴ケ島市」に統一するため、小さなカタカナ「ヶ」とひらがな「が」を大きなカタカナ「ケ」に置換します。
一文字での置換は、リスト内の同様の表記ゆれを統一できます。
import pandas as pd
city_input = pd.Series(['鶴ケ島市', '鶴ヶ島市', '鶴が島市'])
city_replace = city_input.copy() # コピーを作成
for i in range(len(city_replace)): # 文字列の数だけ繰り返す range(3)
city_replace[i] = city_replace[i].replace('ヶ', 'ケ')
city_replace[i] = city_replace[i].replace('が', 'ケ')
print(city_input[i], city_replace[i])
鶴ケ島市 鶴ケ島市
鶴ヶ島市 鶴ケ島市
鶴が島市 鶴ケ島市
左が元の文字列、右が置換後の文字列です。
for文の中で、2回の置換が実行されています。
第一引数の文字列に一致する文字列が、第二引数の文字列に置換されています。
range関数とfor文の使い方は、以下の記事をご覧ください。
>>【Python入門】range関数の使い方(for文で繰り返し処理)
特定の文字列を置換
一文字での置換は、同様の表記ゆれを統一できる一方で、不要な置換をすることがあります。
「つがる市」がリストに含まれていると、「つケる市」になってしまいます。
リストのデータをよく観察して、適切な文字列で置換します。
import pandas as pd
city_input = pd.Series(['鶴ケ島市', '鶴ヶ島市', '鶴が島市', 'つがる市'])
city_replace = city_input.copy() # コピーを作成
for i in range(len(city_replace)): # 文字列の数だけ繰り返す range(3)
city_replace[i] = city_replace[i].replace('鶴ヶ島市', '鶴ケ島市')
city_replace[i] = city_replace[i].replace('鶴が島市', '鶴ケ島市')
print(city_input[i], city_replace[i])
鶴ケ島市 鶴ケ島市
鶴ヶ島市 鶴ケ島市
鶴が島市 鶴ケ島市
つがる市 つがる市
一括処理で文字列を置換
文字列の表記ゆれは、pandasで特定の値を含む行・列を抽出することで、一括して文字列を置換できます。
Pythonのfor文は処理に時間がかかるので、大量のデータを処理するときは一括して処理することをおすすめします。
完全一致する文字列を置換(isin()メソッド)
pandasのisin()メソッドを使用すると、[‘文字列A’, ‘文字列B’]のようなリスト内の文字列と完全一致するデータが抽出できます。
抽出したデータを任意の文字列に書き換えることで、一括して文字列を置換します。
import pandas as pd
city_input = pd.Series(['鶴ケ島市', '鶴ヶ島市', '鶴が島市'])
city_replace = city_input.copy() # コピーを作成
city_replace[city_replace.isin(['鶴ヶ島市', '鶴が島市'])] = '鶴ケ島市'
print(city_input)
print(city_replace)
0 鶴ケ島市
1 鶴ヶ島市
2 鶴が島市
dtype: object
0 鶴ケ島市
1 鶴ケ島市
2 鶴ケ島市
dtype: object
部分一致する文字列を置換(str.contains())
pandasのstr.contains()メソッドを使用すると、 str.contains(‘文字列A’)と部分一致するデータが抽出できます。
str.contains()メソッド は、isin()メソッドと違って’文字列A’を含んだ文字列を抽出します。
リストを使って複数の文字列を指定できないので、対象とする文字列ごとに抽出します。
抽出したデータを任意の文字列に書き換えることで、一括して文字列を置換します。
文字列の抽出は、以下の記事をご覧ください。
>>【Python入門】特定の文字列を含むデータの抽出
import pandas as pd
city_input = pd.Series(['鶴ケ島市', '鶴ヶ島市', '鶴が島市'])
city_replace = city_input.copy() # コピーを作成
city_replace[city_replace.str.contains('鶴ヶ島')] = '鶴ケ島市'
city_replace[city_replace.str.contains('が')] = '鶴ケ島市'
print(city_input)
print(city_replace)
0 鶴ケ島市
1 鶴ヶ島市
2 鶴が島市
dtype: object
0 鶴ケ島市
1 鶴ケ島市
2 鶴ケ島市
dtype: object
まとめ
- 表記ゆれを文字列の置換で統一できました
- 文字列の置換を、繰り返し処理と一括処理で実行できました
- 文字列を、完全一致と部分一致で抽出して置換できました