2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

pandasデータフレーム特定列に対し、条件別で文字列から数値を抽出

Last updated at Posted at 2022-03-25

↓コンペのデータ前処理で、処理時間のかかるコードを書いてしまったため、反省の意味を込めて共有。。
https://www.nishika.com/competitions/25/summary

1. 対象となる処理:

DataFrameのobject型pandas DataFrameにおいて、Object型(文字列型)である特定列から、数値のみ取り出す。

例: 和暦(平成20年, 令和1年)を、西暦(2008, 2019)のように変換。

2. 対象データのイメージ

以下です。
image.png

3. 解決法

以下流れのコードを書きました。
70万行のデータですが、概算2秒弱ほどで処理終了いたしました。
変更前(4.に記載)のコードは10min(600秒)ほどかかりました。

  1. 対象列(column)のuniqueな値をキー、
    和暦と西暦の整合性をとる数字をアイテムとした
    辞書(jap_yeaar)を作る

  2. キーごとに対象indexをリストでとってくる

  3. pandasのstr.extract(("\d+))[0]を使い、
      文字列から数値部分のみとってくる。
     ※イメージ "平成15年" から 15 をとってくる。

  4. 3.でとってきた数値と、辞書(jap_year)のitemを加算する。


jap_year = {"戦前":1920,"昭和":1926,"平成":1989,"令和":2019}

for k in jap_year.keys():
    #indexをリスト型でとってくる。
    index = df_train.index[df_train["建築年"].str.startswith(k) == True].to_list()
    
    if k == "戦前":
        df_train.loc[index,"建築年"] = 1920
    else:
        df_train.loc[index,"建築年"] = df_train.loc[index,"建築年"].str.extract("(\d+)")[0].astype(int) + jap_year[k]

4. 変更前のコード

実行に10分ほどかかるコードです。
re モジュールで文字列から数値を取り出すことが先行し、
70万行あるデータを1行ずつ変更しようとしたものになります。。

import re
import numpy as np

#学習用データ
for i, x in enumerate(df_train["建築年"]):
    
    if pd.isna(x): #欠損値の場合、変換しない。pd.isna()使うと、文字列型の欠損値判定できる。np.isnan()では不可能。
        pass 
    
    elif x[0:2] == "昭和":
        s = df_train["建築年"][i]
        year = int(re.sub(r"\D", "", s))
        df_train["建築年"][i] = year + 1926
        #print(year + 1926)
    elif x[0:2] == "平成":
        s = df_train["建築年"][i]
        year = int(re.sub(r"\D", "", s))
        df_train["建築年"][i] = year + 1989
        #print(year + 1989)
    
    elif x[0:2] == "令和":
        s = df_train["建築年"][i]
        year = int(re.sub(r"\D", "", s))
        df_train["建築年"][i] = year + 2019
        #print(year + 2019)
        
    elif x[0:2] == "戦前":
        df_train["建築年"][i] = 1920

以上です。最後までみていただき、ありがとうございました!

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?