SPSS Modelerの文字列に関するCLEM関数をPythonで書き換える


以下の記事を参照しつつ、SPSS Modelerのclem関数を使って文字列型のレコードを加工してその処理をPythonで書き換えてみます。

加工に使用するデータは、以下から取得しました。
・「データサイエンティスト協会スキル定義委員」の「データサイエンス100本ノック(構造化データ加工編)」https://github.com/The-Japan-DataScientist-Society/100knocks-preprocess
・海外在留邦人数調査統計 https://www.e-stat.go.jp/stat-search/files?page=1&layout=datalist&toukei=00300100&tstat=000001055779&cycle=0&tclass1=000001116075&file_type=1&result_page=1&tclass2val=0

上記の記事で紹介されているとおり、文字列関数の実行結果は主に3種類です。
1. 文字列: String
2. 文字の位置: Integer ※
3. 真(1)偽(0): Boolean (この記事では実行例割愛)
※SPSS Modelerの添え字が1から始まるのに対してPythonは0から始まるため注意が必要です。

1. 結果を文字列で返す関数

1. 部分文字列の抽出

1. 先頭/末尾N文字

[実行例]
例1: 地域名の先頭のローマ数字のみ抽出
例2: 生年月日の日付のみ抽出
   ※日付型としての処理については以下の記事を参照
   https://qiita.com/kawada2017/items/0546580314f5b67408b1
例3: コードの末尾1文字を抽出

◇ SPSS Modeler
例1: startstring(N,'<フィールド名>')
例2: endstring(N,to_string(<フィールド名>))
例3: last(<フィールド名>)

◇ Python
例1: <データフレーム名>['<カラム名>'].str[:N-1]
例2: <データフレーム名>['<カラム名>'].str[-N:]
例3: <データフレーム名>['<カラム名>'].str[:-1]

df_zairyu_houjin['region_cd'] = df_zairyu_houjin['地 域'].str[:1]
df_customer['day_of_birthday'] = pd.to_numeric(df_customer['birth_day'].str[-2:])
df_customer['status_last_char'] = df_customer['status_cd'].str[-1]

2. N番目の文字を抽出

[実行例]
例1: 年月日フィールドの年の末尾(4番目)の文字を抽出
例2: 店舗コードの各県ごとに採番されたID(4番目から3文字)を抽出
例3: 年月日フィールドの月(5,6番目)の文字を抽出
例4: '-'区切りのコードの2番目の部分文字列を抽出

◇ SPSS Modeler
例1: subscrs(N,<フィールド名>)
例2: substring(N1(開始位置),N2(終了位置), <フィールド名>))
例3: substring_between(N1(開始位置),N2(終了位置),<フィールド名>)
例4: textsplit(<フィールド名>,N,'<区切り文字>')

◇ Python
例1: <データフレーム名>['<カラム名>'].str[N]
例2: <データフレーム名>['<カラム名>'].str[N1:N2]
例3: <データフレーム名>['<カラム名>'].str[N1:N2]
例4: <データフレーム名>['<カラム名>'].str.split('<区切り文字>',expand=True)

df_customer['application_year_last'] = df_customer['application_date'].astype(str).str[3]
df_store['store_num'] = df_store['store_cd'].str[3:6].astype(int)
df_customer['application_month'] = df_customer['application_date'].astype(str).str[4:6]
df_customer['status_mid'] = df_customer['status_cd'].str.split('-',expand=True)[1]

2. 部分文字列の削除

1. 文字列の先頭/末尾のN字を削除

[実行例]
例1: 商品コード(product_cd)から接頭文字(P)を削除
例2: 店舗名(store_name)から「店」を削除

◇ SPSS Modeler
例1: allbutfirst(N, <フィールド名>)
例2: allbutlast(N, <フィールド名>)

◇ Python
例1: <データフレーム名>['<カラム名>'].str[N-1:]
例2: <データフレーム名>['<カラム名>'].str[:-N]

df_product['product_code_int'] = pd.to_numeric(df_product['product_cd'].str[1:])
df_store['store_without_ten'] = df_store['store_name'].str[:-1]

2. 先頭や末尾の空白文字を削除

[実行例]
接頭辞を削除した地域名の空白文字を削除

◇ SPSS Modeler
先頭の空白文字を削除: trimstart(<フィールド名>)
末尾の空白文字を削除: trimend(<フィールド名>)
先頭および末尾の空白文字を削除: trim(<フィールド名>)
※ 末尾の空白文字の削除例は割愛、今回の例では実行結果は先頭/先頭および末尾で同一のため先頭および末尾の例を記載

◇ Python
先頭の空白文字を削除: <データフレーム名>['<カラム名>']str.lstrip()
末尾の空白文字を削除: <データフレーム名>['<カラム名>']str.rstrip()
先頭および末尾の空白文字を削除: <データフレーム名>['<カラム名>']str.strip()

df_zairyu_houjin['region_name'] = df_zairyu_houjin['地\u3000域'].str[1:].str.lstrip()
df_zairyu_houjin['region_name'] = df_zairyu_houjin['地\u3000域'].str[1:].str.rstrip()
df_zairyu_houjin['region_name'] = df_zairyu_houjin['地\u3000域'].str[1:].str.strip()

3. 特定の文字列の削除

[実行例]
文字列中の"E"をすべて削除

◇ SPSS Modeler
stripchar(<CHAR>, <フィールド名>)

◇ Python

_<データフレーム名>_['_<カラム名>_']str.replace("_CHAR_","")

※Pythonのstrip系の関数の引数に文字列をとると先頭もしくは末尾から削除可能。ただし中間部の文字は削除できないためreplace関数を使用

3. 文字列の置換

1. 任意の文字列間の置換

[実行例]
カテゴリー名を「惣菜」から「デリカ」へ置換

◇ SPSS Modeler
replace('<置換前文字列>','<置換後文字列>',<フィールド名>)

◇ Python
df_category['new_cate'] = df_category['category_major_name'].str.replace('惣菜','デリカ')

2. 大文字/小文字変換

◇ SPSS Modeler
大文字から小文字: uppertolower(<フィールド名>)
小文字から大文字: lowertoupper(<フィールド名>)
※小文字から大文字への変換例は割愛

◇ Python
大文字から小文字: <データフレーム名>['<カラム名>']str.lower()
小文字から大文字: <データフレーム名>['<カラム名>']str.upper()
※小文字から大文字への変換例は割愛

df_sampletran['l_class_lower'] = df_sampletran['L_CLASS'].str.lower()

4. その他の文字列を返す処理

1. 指定文字列のN個のコピーからなる文字列

◇ SPSS Modeler
replicate(N,'<文字列>')

◇ Python
['<文字列>' * N for i in <データフレーム名>.index]
  データフレームに新しいカラムを追加し、インデックスの数だけ指定文字列を繰り返した値を挿入している

df_sampletran['repeat_times_by_index'] = ['abc' * (i + 1) for i in df_sampletran.index]

2. Unicode値から文字への変換

◇ SPSS Modeler
unicode_char(N)
  ※10進数で入力する、16進数には対応していない

◇ Python
chr(N)

df_sampletran['unique_char_by_index'] = [chr(65+i) for i in df_sampletran.index]

2. 結果を数値で返す関数

1. 部分文字列の位置の取得

◇ SPSS Modeler

1. 部分文字列が値に含まれる場合に添え字を返す

issubstring('<部分文字列>', <フィールド名>)

2. 部分文字列が値の先頭に含まれる場合に添え字を返す

isstartstring('<部分文字列>', <フィールド名>)

3. 部分文字列が値の中間に含まれる場合に添え字を返す

ismidstring('<部分文字列>', <フィールド名>)

4. 部分文字列が値の末尾にある場合に添え字を返す

isendstring('<部分文字列>',<フィールド名>)

◇ Python

1. 部分文字列が値に含まれる場合に添え字を返す

<データフレーム名>['<カラム名>'].str.find('<部分文字列>') + 1

df_customer['dai_index'] = df_customer['customer_name'].str.find('大') + 1

2. 部分文字列が値の先頭に含まれる場合に添え字を返す

<データフレーム名>['<カラム名>'].str.startswith('<部分文字列>') * 1
※startswithで審議値を取得し"*1"で数値に変換

df_customer['tomin_flg'] = df_customer['address'].str.startswith('東京都') * 1

3. 部分文字列が値の中間に含まれる場合に添え字を返す

[<データフレーム名>['<カラム名>'][i].find('<部分文字列>')+1 if <データフレーム名>[1:-1].find('<部分文字列>') != -1 else 0 for i in range(len(<データフレーム名>))]
※値の先頭と末尾から1文字削除した後で部分文字列が含まれる場合は添え字+1を返している 例: 値が"abcdcba"で部分文字列が"bc"の場合先頭と末尾から1文字を削除した"bcdcba"に"bc"が含まれるため"abcdcba"中の"bc"の添え字+1である2を返す

df_customer['mid_ta_index'] = [df_customer['customer_name'][i].find(substr)+1 if df_customer['customer_name'][i][len(substr):-len(substr)].find(substr) != -1 else 0 for i in range(len(df_customer))]

4. 部分文字列が値の末尾にある場合に添え字を返す

[rfind('<部分文字列>')+1 if <データフレーム名>['<カラム名>'][i].endswith('<部分文字列>') else 0 for i in range(len(<データフレーム名>'))]

df_store['chome_index'] = [df_store['address'][i].rfind('丁目')+1 if df_store['address'][i].endswith('丁目') else 0 for i in range(len(df_store))]

2. 部分文字列の登場回数の取得

◇ SPSS Modeler
count_substring(<フィールド名>,'<部分文字列>')

◇ Python
<データフレーム名>['<カラム名>'].str.count('<部分文字列>')

df_customer['count_higashi'] = df_customer['address'].str.count('東')

3. 文字列の長さの取得

◇ SPSS Modeler
length(<フィールド名>')

◇ Python
<データフレーム名>['<カラム名>'].str.len()

df_customer['name_length'] = df_customer['customer_name'].str.len()

お断り

このサイトの掲載内容は私自身の見解であり、必ずしも所属会社の立場、戦略、意見を代表するものではありません。 記事は執筆時点の情報を元に書いているため、必ずしも最新情報であるとはかぎりません。 記事の内容の正確性には責任を負いません。自己責任で実行してください。