見出し画像

前処理大全:第3章

前回に引き続き「前処理大全」の内容をまとめた記事です。今回は第3章をPythonで書いたので参考にして頂けたら嬉しいです。

前回の記事を読んでない方はそちらから見て頂ければなと。

第3章:集約

3-1:データ数、種類数の算出

# groupby関数でreserve_idを集約単位に指定して、size関数でデータ数をカウント
# groupby関数の集約で行番号(index)が飛び飛びになってるので、reset_index関数によって集約単位に指定したhotel_idを集約した状態から
# 列名に戻し新たな現在の行番号に直す
rsv_cnt_tb = reserve_tb.groupby('hotel_id').size().reset_index()
rsv_cnt_tb
# 集約結果の列名を設定
rsv_cnt_tb.columns = ['hotel_id', 'rsv_cnt']
rsv_cnt_tb
# gruoupby関数でhotel_idを集約単位に指定し、customer_idの値をnunique関数にすることで顧客数をカウント
cus_cnt_tb = reserve_tb.groupby('hotel_id')['customer_id'].nunique().reset_index()
cus_cnt_tb
# 集約結果の列名を設定
cus_cnt_tb.columns = ['hotel_id', 'cus_cnt']
cus_cnt_tb
# merge関数を用いてhotel_idを結合キーにして結合
pd.merge(rsv_cnt_tb, cus_cnt_tb, on = 'hotel_id')

ホテルID毎の予約数と予約した事のある人の人数を集約できました。このcodeは予約数の集計結果と顧客数の集計結果が別々のDateFrameと出力されてます。そのため、集約結果をまとめるために結合処理をしなければいけないので本書ではおすすめのcodeとしては紹介されてません。下記がおすすめのcodeとして紹介されてます。

# agg関数を使用して集約処理をまとめて指定
# reserve_idを対象にcount関数を適用
# customer_idを対象にnunique関数を適用
result = reserve_tb.groupby('hotel_id').agg({'reserve_id':'count', 'customer_id': 'nunique'})

# reset_index関数によって、列番号を振り直す(inplace = Trueなので直接resultを更新)
result.reset_index(inplace = True)
result.columns = ['hotel_id', 'rsc_cnt', 'cus_cnt']

result

3-2:合計値の算出

Q:ホテル毎の宿泊人数別の合計予約金額を算出

# 序盤で宿泊人数と予約金額を消してたので作り直し
reserve_tb = pd.read_csv('reserve.csv', encoding = 'UTF-8')

# 集約単位をhotel_idとpeople_numの組み合わせを指定
# 集約したデータからtotal_priceを取り出し。sum関数を適用することで売り上げ合計金額を算出
result = reserve_tb.groupby(['hotel_id', 'people_num'])['total_price'].sum().reset_index()

# 売り上げ合計金額の列名がtotal_priceになってるので、price_sumに変更
result.rename(columns={'total_price' : 'prise_sum'}, inplace=True)
reslut

3-3:極値、代表値の算出

Q:ホテル毎の予約金額の最大値、最小値、平均値、中央値、20%タイル値(近似値でも可)を出力

# total_priceを対象に「mac,min,mean,median」関数を使用
# Pythonのラムダ式をagg関数の集約に指定
# ラムダ式にはnumpy.percentileを指定しパーセントタイル値を算出(パーセントは20%を指定)
result = reserve_tb.groupby('hotel_id').agg({'total_price' : ['max', 'min', 'mean', 'median', lambda x : np.percentile(x, q = 20)]}).reset_index()
result.columns =['hotel_id', 'price_max', 'price_min', 'price_mean', 'price_median', 'price_20per']
result

3-4:ばらつき具合の算出

Q:各ホテルの予約金額の分散値と標準偏差値を算出

# total_priceに対してvar関数とstd関数を使って分散と標準偏差を算出
result = reserve_tb.groupby('hotel_id').agg({'total_price' : ['var', 'std']}).reset_index()
result.columns = ['hotel_id', 'price_var', 'price_std']
result

3-5:最頻値の算出

Q:予約金額を1000単位にカテゴリ化して最頻値を算出

result = reserve_tb['total_price'].round(-3).mode
result

3-6:順位の算出

Q:顧客毎に予約日時の古い順を求める同じ日時の場合はデータの読み込み順に小さな順位をつける

# rank関数で並び替えるために、データ型を文字列型からtimestamp型に変換
reserve_tb['reserve_datetime'] = pd.to_datetime(reserve_tb['reserve_datetime'], format = '%Y-%m-%d %H:%M:%S')

# log_noを改列として追加
# 集約単位の指定はgroupbyを利用
# 顧客毎にまとめたresercve_datetimeを生産し、rank関数によって順位を生産
# ascendingをTrueいして昇順に設定
reserve_tb['log_no'] = reserve_tb.groupby('customer_id')['reserve_datetime'].rank(ascending = True, method = 'first')
reserve_tb

Q:ホテル毎の予約数に順位付けをして、予約数が同じ場合はどう予約数の全ホテルに最小の順位を付ける

# hotel_id毎の件数(予約件数)を計算して、結果を’rsv_cnt’列とする
rsv_cnt_tb = reserve_tb.groupby('hotel_id').size().reset_index()
rsv_cnt_tb.columns = ['hotel_id', 'rsv_cnt']

# 'rsv_cnt'を元にrank関数で順位付け
# ascendingをFalceにする事で高順に指定
# methodをminに設定し、同じ値の場合はとりえる最小順位に指定
rsv_cnt_tb['rsv_cnt_rank'] = rsv_cnt_tb['rsv_cnt'].rank(ascending=False, method = 'min')

# 必要のない'rsv_cnt'列を削除
rsv_cnt_tb.drop('rsv_cnt', axis = 1, inplace = True)

rsv_cnt_tb

まとめ

各課題に対してのコードとその説明を記載しました。次は第4章の解説記事を書きますので、興味のある方はチェックしてみてください。

サポートして頂いたお金は開業資金に充てさせて頂きます。 目標は自転車好きが集まる場所を作る事です。 お気持ち程度でいいのでサポートお願い致します!