お疲れさまです、Yuinaです🍵
本日は、Pythonの100本ノック・第5章の解説をお届けします。
使用している環境は以下のとおりです。
- 実行環境:Google Colaboratory
- OS:macOS
どうぞよろしくお願いいたします!
ノック41本目:データの読み込みと整形
import pandas as pd
customer = pd.read_csv('/content/customer_join.csv')
uselog_months = pd.read_csv('/content/use_log_months.csv')
5章ではジムの利用者データについて分析をしています。
まずはcustomer_join.csvとuse_log_months.csvを取り込みます。
customer_join.csvの中身はこんな感じです。


※おさまらなかったので画像2枚にしました。
会員区分やキャンペーン区分など詳細な会員データが入っているファイルみたいですね。
use_log_month.csvはこちらです。

ジムの利用履歴データみたいです。
ここからは、当月と過去1ヶ月の利用回数を集計したデータを作成します。
year_months = list(uselog_months['年月'].unique())
uselog = pd.DataFrame()
まず、uselog_monthsのデータフレームから年月(カラム名)のデータを取得します。
続いて、uselog = pd.DataFrame()で当月と前月のデータを統合したデータを格納する空のデータフレームを用意します。
for i in range(1,len(year_months)):
tmp = uselog_months.loc[uselog_months["年月"]==year_months[i]].copy()
tmp.rename(columns={"count":"count_0"},inplace=True)
tmp_before = uselog_months.loc[uselog_months["年月"]==year_months[i-1]].copy()
del tmp_before["年月"]
tmp_before.rename(columns={"count":"count_1"},inplace=True)
当月分のデータを入れ込んでいきます。
for文ですが、最初の月には前月データがないため、1
からループを開始します。
uselog_months.loc[uselog_months[“年月”]==year_months[i]].copy()は、
uselog_months
の中から、年月のカラムのデータが特定の月と一致する行だけを取り出します。
最後にcount 列をcount_0
に名前変更します。
続いて先月分のデータを見ていきます。
tmp_before = uselog_months.loc[uselog_months[“年月”]==year_months[i-1]].copy()は
uselog_monthsの年月のカラムから前月のデータを抽出し、削除します。
最後にcount列をcount_1に名前変更します。
続いて、データをマージ(結合)していきます。
tmp = pd.merge(tmp,tmp_before,on="customer_id",how="left")
当月(tmp)と前月(tmp_before)の利用回数を横並びにしたものをtmpに代入します。
uselog = pd.concat([uselog,tmp],ignore_index=True)
作成した当月+前月のデータをuselog
に追加します。

結果こんな表が出来上がりました。
<table cellpadding="0" cellspacing="0" border="0" style=" border:1px solid #ccc; /*width:300px*/;"><tbody><tr style="border-style:none;"><td style="vertical-align:top; border-style:none; padding:10px; /*width:44px*/ width:86px;"><a href="https://rpx.a8.net/svt/ejp?a8mat=453FFM+DG1FLE+2HOM+BWGDT&rakuten=y&a8ejpredirect=https%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00s3dw4.2bo11f3f.g00s3dw4.2bo12678%2Fa25042272339_453FFM_DG1FLE_2HOM_BWGDT%3Fpc%3Dhttps%253A%252F%252Fitem.rakuten.co.jp%252Fautumn1%252F2831-021%252F%26amp%3Bm%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Fautumn1%252Fi%252F10269760%252F%26amp%3Brafcid%3Dwsc_i_is_33f72da33714639c415e592c9633ecd7" rel="nofollow"><img border="0" alt="" src="https://thumbnail.image.rakuten.co.jp/@0_mall/autumn1/cabinet/apide2024saika/image01/2831-021.jpg?_ex=64x64" /></a></td><td style="font-size:12px; vertical-align:middle; border-style:none; padding:10px;"><p style="padding:0; margin:0;"><a href="https://rpx.a8.net/svt/ejp?a8mat=453FFM+DG1FLE+2HOM+BWGDT&rakuten=y&a8ejpredirect=https%3A%2F%2Fhb.afl.rakuten.co.jp%2Fhgc%2Fg00s3dw4.2bo11f3f.g00s3dw4.2bo12678%2Fa25042272339_453FFM_DG1FLE_2HOM_BWGDT%3Fpc%3Dhttps%253A%252F%252Fitem.rakuten.co.jp%252Fautumn1%252F2831-021%252F%26amp%3Bm%3Dhttp%253A%252F%252Fm.rakuten.co.jp%252Fautumn1%252Fi%252F10269760%252F%26amp%3Brafcid%3Dwsc_i_is_33f72da33714639c415e592c9633ecd7" rel="nofollow">アマノフーズ&永谷園食卓セット BS-25R 内祝い お返し ギフトセット 出産内祝い 結婚内祝い お供え 御供 香典返し 粗供養 快気祝い 快気内祝い</a></p><p style="color:#666; margin-top:5px line-height:1.5;">価格:<span style="font-size:14px; color:#C00; font-weight:bold;">1620円</span><br/><span style="font-size:10px; font-weight:normal;">(2025/4/23 00:01時点)</span><br/><span style="font-weight:bold;">感想(0件)</span></p></td></tr></tbody></table>
<img border="0" width="1" height="1" src="https://www11.a8.net/0.gif?a8mat=453FFM+DG1FLE+2HOM+BWGDT" alt="">
ノック42本目:退会前月の顧客データ作成
このジムは月末までに退会申請をして、翌月末で退会できるシステムです。
退会を未然に防ぐことが目的であるため、退会前月のデータを作成します。
from dateutil.relativedelta import relativedelta
relativedeltaのデータは、timedeltaと同じように日付や日付時刻に足したり引いたりできます。 relativedeltaは、dateutil.relativedeltaモジュールで定義されています。「Xヶ月後」「X年後」を計算できます(参照)
exit_customer = customer.loc[customer["is_deleted"]==1].copy()
customer データから、退会した顧客(is_deleted == 1)だけを取り出して新しいデータフレームを作成します。
exit_customer["exit_date"] = None
exit_date(退会前月)の入れ物を準備します。
exit_customer["end_date"] = pd.to_datetime(exit_customer["end_date"])
次にend_date(退会日)を日時型に変換し、それを元に退会前月データの準備します。
ちょっとわかりにくかったので別の書き方をしてみました。
# 日付として扱うために型変換
exit_customer["end_date"] = pd.to_datetime(exit_customer["end_date"])
# 1ヶ月引いた日付をまとめて計算
exit_customer["exit_date"] = exit_customer["end_date"] - pd.DateOffset(months=1)
# 形式変換
exit_customer["年月"] = exit_customer["exit_date"].dt.strftime("%Y%m")
exit_customerはこのように表示されました。

次にuselogのカラム年月を文字列にして、exit_customerのカラム年月と形式を揃えています。
uselog["年月"] = uselog["年月"].astype(str)
exit_uselog = pd.merge(uselog, exit_customer, on=["customer_id", "年月"], how="left")
ここではuselog と exit_customer を「customer_id と 年月 が一致するもの同士」で結合します。
その結果,exit_customerはこのようになりました。


欠損値(NaN)がいっぱいあります。
データが欠損していないものだけ残して、あとは除外します。
exit_uselog = exit_uselog.dropna(subset=["name"])
print(len(exit_uselog))
print(len(exit_uselog["customer_id"].unique()))
exit_uselog.head()

綺麗になりました。
まとめ
今回はデータの読み込みと整形、そして退会前月の退会顧客のデータを作成しました。
次回は継続顧客のデータの作成からやっていきます。
ありがとうございました。
コメント