目的
アンケートなどを集計する時に、良い(5)、まあ良い(4)、どちらでもない(3)、あまり良くない(4)、良くない(5)といった順序尺度を「良い」、「悪い」の2値に分けたい場面があります。pythonではどのようにデータを加工すれば良いのでしょうか。
使用するデータ
SIGNATEさんの練習問題として公開されている「レンタル自転車の利用者予測」 のtrain dataを使います。日曜日を0、月曜日を1、曜日が進むについて1つずつ増えて、土曜日が6になるデータがあります。これを土日を0として、平日を1にしたい場合どういうコードを実行すれば良いのでしょうか。
曜日データ'weekday'の確認
まずはデータを読み込みます。データフレームを使いますので、pandasも読み込みます。
import pandas as pd
df = pd.read_csv('ファイルのパスをコピペして下さい')
曜日の変数名は'weekday'です。'weekday'のデータ数と内訳を確認します。
df_1 = df['weekday']
print(df_1.count())
print() #空行を作るため
print(df_1.value_counts().sort_index())
件数が8645件、0から6までの合計と一致しますね。これを土曜日(6)と日曜日(0)を0、月曜日(1)から金曜日(5)までを1の2値データに変換します。
for文
tmplist=[]
for i in df_1:
if i in [0,6]:
tmplist.append(0)
elif i in list(range(1,6)):
tmplist.append(1)
else:
next
print(pd.DataFrame(tmplist).value_counts())
# 新たに変数'weekday2'を作成して、tmplistの結果を代入する
df['weekday2']= tmplist
print(df['weekday2'].value_counts())
# train data (df)に'weekday2'が追加されているか確認する
df.head()
出力結果を見ると、土日と平日の数は同じですし、'weekday2'が新しく追加されています。
while文
新しい変数'weekday2'を作って0(ゼロ)を代入します。そしてwhile文で平日を1に書き換えるというアプローチです。
df_weekday = df.copy()
df_weekday['weekday2'] = 0
i = 0
while i <= 8644: #8645件あるが、ゼロオリジンなので、8644
if df_weekday.iloc[i, 7] in [1,2,3,4,5]: #i行7列目としてweekday列を指定
df_weekday.iloc[i, 15] = 1 #15列目としてweekday_平日を指定
i += 1
df_weekday['weekday2'].value_counts()
value_countsの結果が土日が2495件、平日が6150件で正しく出力されています。
isin
アプローチはwhile文と同じですが、よりシンプルなコードで実行できます。
df_isin = df.copy()
df_isin['weekday2'] = 0 #新しい変数'weekday2'を作って、全て0(zero)を入れる
# 平日を1にしたいので、1にするコードを用意する
df_isin.loc[df['weekday'].isin(list(range(1,6))),'weekday2']=1
df_isin['weekday2'].value_counts()
value_countsの結果が土日が2495件、平日が6150件で正しく出力されています。
まとめ
for文、while文、isinそれぞれ2値にわけることができました。コードのシンプルさという意味ではisinが便利でした。
・新しい変数を用意して、
・そこに一旦すべて0を入れ込んで、
・平日だけ1に変換する
というアプローチでした。