【Python実践データ分析100本ノック】ノック21-25

python実践データ分析100本ノック解説 python データ分析
スポンサーリンク

本記事では学習のアウトプットとして、『Python実践データ分析100本ノック』に書かれている各ノックのコードのうち、難解と思われる部分の意味を解説していきます。 「本に書かれている解説だけでは理解が難しい(;一_一)」と感じた方、この記事を読んで理解の一助となれば幸いです。

Python実戦データ分析100本ノックは、データの集計や分析のためのpandasや、グラフ描画に使用するmatplotlib、機械学習を行うためのscikit-learnなど、データ分析に欠かせない要素を実際に自分で手を動かしながら学ぶことができる本です。

今回は第5回として、ノック21-25をやっていきます。

 

追記現在第二版が2022年6月に出版されています

本記事は第1版の内容の解説です

第二版の解説記事もいずれ書かせていただこうと思っていますので今しばしお待ちください!

スポンサーリンク

第3章 顧客の全体像を把握するノック10本

ノック21:データを読み込んで把握しよう

uselog = pd.read_csv(‘use_log.csv’)
print(len(uselog))
uselog.head()

customer = pd.read_csv(‘customer_master.csv’)
print(len(customer))
customer.head()

class_master = pd.read_csv(‘class_master.csv’)
print(len(class_master))
class_master.head()

campaign_master = pd.read_csv(‘campaign_master.csv’)
print(len(campaign_master))
campaign_master.head()

これまでと同様にデータを読み込みました。

ノック22:顧客データを整形しよう

#ノック3や4からやっているのと同様にcustomerをベースにclass_masterを結合しています。
customer_join = pd.merge(customer, class_master, on="class", how="left")
customer_join = pd.merge(customer_join, campaign_master, on="campaign_id", how="left")
customer_join.head()

customer と class_master を class 列をキーとして結合し、customer_join というデータを作りました。その後、campaign_master のcampaign_id列をキーとしてcustomer_joinに結合しました。

ノック23:顧客データの基礎集計をしよう

#count()は対象のデータを[]内の値で数えていきます。
customer_join.groupby("class_name").count()["customer_id"]
customer_join.groupby("campaign_name").count()["customer_id"]
customer_join.groupby("gender").count()["customer_id"]
customer_join.groupby("is_deleted").count()["customer_id"]

#ノック8と同様にstart_dateを日時を表す文字列datetimeに変換しています。
customer_join["start_date"] = pd.to_datetime(customer_join["start_date"])
#loc関数を用いて上の行でdatetime型にしたstart_dateと同じくdatetime型にした20180401を比較して、start_dateが20180401よりも後(2018年4月1日以降に入会した)であればcustomer_startに格納します。
customer_start = customer_join.loc[customer_join["start_date"]>pd.to_datetime("20180401")]
print(len(customer_start))

2018年4月1日 より後に入会した人を集計し、customer_startに格納できました。

ノック24:最新顧客データの基礎集計をしよう

#ノック8と同様にend_dateを日時を表す文字列datetimeに変換しています。
customer_join["end_date"] = pd.to_datetime(customer_join["end_date"])
#isna()は初見ですが、ノック7から使用しているisnull()と同じ意味の関数です。
#loc関数の中の条件式の意味ですが、
#1つ目の条件は、ノック23と同じような要領で今度はend_dateをdatetime型に変換し、datetime型の20190331と比較して、end_dateが20190331よりも後(2019年3月31日以降に退会した)であること
#2つ目の条件は、end_dateが空データであること
#1つ目と2つ目の条件の"|(or)"をとって、条件を満たすデータをcustomer_newerに格納します。
customer_newer = customer_join.loc[(customer_join["end_date"]>=pd.to_datetime("20190331"))|(customer_join["end_date"].isna())]
print(len(customer_newer))
customer_newer["end_date"].unique()

2019年3月31日以降に退会した人、もしくは、まだ退会していない人を集計し、customer_newerに格納しました。

ノック25:利用履歴データを集計しよう

#ノック8と同様にusedateを日時を表す文字列datetimeに変換しstrftime関数で年月の形式にした後、年月という変数に格納しています。
uselog["usedate"] = pd.to_datetime(uselog["usedate"])
uselog["年月"] = uselog["usedate"].dt.strftime("%Y%m")
#ノック8から使用しているgroupbyですが、デフォルトではグループ化した際にラベル(0,1,2,3,,)がそのままindexになります。
#しかし、そのindexにしたくないとき、as_index=Falseとします。
#"年月"そしてcustomer_idごとに集計し、uselog_monthという変数に格納します。
uselog_months = uselog.groupby(["年月","customer_id"],as_index=False).count()
#rename()は{元の値: 新しい値}の形で指定した(今回はlog_id)をその右で指定した値(count)で書き替えます。
#さらに、rename()はデフォルトでは元のデータフレームが変更されず、新しいデータフレームが返されます。
#引数inplaceをTrueにすると、元のデータフレームが変更されます。
uselog_months.rename(columns={"log_id":"count"}, inplace=True)
#delでusedateを削除します。
del uselog_months["usedate"]
uselog_months.head()

#agg関数は1つの対象に対して、引数に指定した集計単位で同時に複数の集計を行うことができます。
#今回はuselog_monthsのcustomer_idの平均値、中央値、最大値、最小値を一気に集計しています。
uselog_customer = uselog_months.groupby("customer_id").agg(["mean", "median", "max", "min" ])["count"]
#reset_index関数でインデックスをリセットします。今回はindexを0,1,2,3と表示させたいので、drop=Falseとしています。
uselog_customer = uselog_customer.reset_index(drop=False)
uselog_customer.head()

これで顧客ごとの月内利用回数をまとめる事ができました。

ここまでで、ノック21-25は完了です。お疲れ様でした。 読み込んだデータの集計を中心に行いました。 次回は3章後半に入ります。引き続きよろしくお願いいたします(^^)/。