Pandasで文字列から数字以外を抽出
今回の記事は、競馬データを加工していく中で正規表現を使ってコラムを分けたい時によく出てくるのでメモとして記載しておきます。したい事
データフレーム内のあるコラムでは、数字と文字が混合している場合があります。例:
test_list = ["1中山2", "11中京2", "阪神2"]
df = pd.DataFrame(test_list, columns={"開催場所"})
print(df)
# 開催場所
#0 1中山2
#1 11中京2
#2 阪神1
上記のデータの開催場所で、数字以外を抽出したい場合には正規表現を使って分割しましょう
解決策
import regex
df['開催場所'].apply(lambda x: regex.subn(r'\d', '', x))
print(df['開催場所'].apply(lambda x: regex.subn(r'\d', '', x))
#0 (中山, 2)
#1 (中京, 3)
#2 (阪神, 1)
df["開催場所_new"] = df['開催場所'].apply(lambda x: regex.subn(r'\d', '', x)[0])
print(df)
# 開催場所 開催場所_new
#0 1中山2 中山
#1 11中京2 中京
#2 阪神1 阪神
解説
regex.subn()の使いとして、第一因数に正規表現を指定し、第二因数に正規表現に一致する文字を変更する文字の指定、第三因数に文字列を指定して使います。以下の例では、30という数字を10に変更する方法を記載しています。
例:
test_txt = "今日の天気は、30度"
"""
30度を10度に変更します。
正規表現としては、30という数字部分を一致させたいので、r'\d*'と指定します。
30を10に変更したいので、第二因数は"10"に指定します。
実行結果は、タプル型の値を返します。
一つ目の値としては、変更後の文字列を返します。
二つ目の値としては、正規表現に一致する個数を返します。
"""
print(regex.subn(r"\d+", "10", test_txt))
# ("今日の天気は、10度", 1)
"""
上では、正規表現をr"\d+"として連続する数値<を探すようにしていました。
下では、正規表現をr"\d"として数値を探すようにしました。
実行結果は、数字がある箇所に10に置き換えられるため、1010度となっています。
又、正規表現に一致する個数は、2個となっています。
"""
print(regex.subn(r"\d", "10", test_txt))
# ("今日の天気は、1010度", 2)
自身のまちがい
元々のコードprint(df['開催場所'].str.split("\d+", expand=True))
# 0 1 2
#0 中山
#1 中京
#2 阪神 None
df["開催場所_new"] = df['開催場所'].str.split("\d+", expand=True)[1]
print(df)
# 開催場所 開催場所_new
#0 1中山2 中山
#1 11中京2 中京
#2 阪神1
自身としてはpandasのstr.split()でいけると思っていたが、これだと先頭に数字がない場合には同じコラムに数字以外の文字が値が返されていません。
そのため、結合してもNoneとなる行が存在します。
[参考資料]
regexについて
https://note.nkmk.me/python-re-regex-character-type/