0
0

More than 3 years have passed since last update.

実践データ分析 ノック21~30

Last updated at Posted at 2020-03-04

ノック21:データの読み込み

ノック21.py
#ジムの利用履歴データ
import pandas as pd
uselog=pd.read_csv("/content/use_log.csv")
print(len(uselog))
uselog.head()

image.png

ノック21.py
#2019年3月末時点での会員データ
customer=pd.read_csv("/content/customer_master.csv")
print(len(customer))
customer.head()

image.png

ノック21.py
#会員区分データ(オールタイム、デイタイム、ナイト)
class_master=pd.read_csv("/content/class_master.csv")
print(len(class_master))
class_master.head()

image.png

ノック21.py
#キャンペーン区分データ(入会費無料等)
campaign_master=pd.read_csv("/content/campaign_master.csv")
print(len(campaign_master))
campaign_master.head()

image.png

データの長さを見て、主とするデータはcustomer(顧客データ),uselog(利用履歴)をするのがいい!
まず、データ数の少ないcustomer(顧客データ)から主に考えていく!

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

ノック22.py
#customerを元に、class列,campaign_id列を軸に、カラム名を増やす!
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()

image.png

ノック22.py
#欠損値の確認
customer_join.isnull().sum()

image.png

元のcustomer(顧客データ)…customer_id,name,class,gender,start_date,end_date,campaign_id,is_delete
以外のclass_name,price,campaign_nameがカラムに追加されていることが確認できる!

ノック23:顧客データの基礎集計

ノック23.py
#どの会員に属しているかの数を調べる
customer_join.groupby("class_name").count()["customer_id"]

image.png

ノック23.py
#どのキャンペーンで入会したかの数を調べる
customer_join.groupby("campaign_name").count()["customer_id"]

image.png

ノック23.py
#男女の数を調べる
customer_join.groupby("gender").count()["customer_id"]

image.png

ノック23.py
#ジムを退会した数を調べる
customer_join.groupby("is_deleted").count()["customer_id"]

image.png

ノック23.py
#2018年4月1日~2019年3月31日
customer_join["start_date"]=pd.to_datetime(customer_join["start_date"])
customer_start=customer_join.loc[customer_join["start_date"]>pd.to_datetime("20180401")]
print(len(customer_start))
>>>1361

2018年4月1日~2019年3月31日の入会会員は1361人、退会会員は1350人と全体の会員数はあまり変わってないことが分かる!

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

ノック24.py
#2019年3月時点において在籍している会員数を調べる
customer_join["end_date"]=pd.to_datetime(customer_join["end_date"])
customer_newer=customer_join.loc[(customer_join["end_date"]>=pd.to_datetime("20190331")) | (customer_join["end_date"].isna())]#isna()はNanの時、Trueを返す
print(len(customer_newer))
customer_newer["end_date"].unique()

image.png

ノック24.py
#2019年3月時点において在籍している,どの会員に属しているかの数を調べる
customer_newer.groupby("class_name").count()["customer_id"]

image.png

ノック24.py
#2019年3月時点において在籍している,どのキャンペーンで入会したかの数を調べる
customer_newer.groupby("campaign_name").count()["customer_id"]

image.png

ノック24.py
#2019年3月時点において在籍している,男女の数を調べる
customer_newer.groupby("gender").count()["customer_id"]

image.png

出力結果を見ると、会員区分、性別は全体で集計した時とあまり変化はない。
しかし、キャンペーン区分に関しては若干違いがある(通常入会72%→81%)
つまり、入会キャンペーンは何かしらの硬貨を生んでいることが分かる。

ノック25:利用履歴データを集計する

ノック25.py
uselog["usedate"]=pd.to_datetime(uselog["usedate"])#datetime型変換
uselog["年月"]=uselog["usedate"].dt.strftime("%Y%m")#年、月のみ取得
uselog_months=uselog.groupby(["年月","customer_id"],as_index=False).count()
uselog_months.rename(columns={"log_id":"count"},inplace=True)
del uselog_months["usedate"]
uselog_months.head()

image.png

注意!

ノック25.py
uselog["usedate"]=pd.to_datetime(uselog["usedate"])#datetime型変換
uselog["年月"]=uselog["usedate"].dt.strftime("%Y%m")#年、月のみ取得
uselog_months=uselog.groupby(["年月","customer_id"]).count()
uselog_months.rename(columns={"log_id":"count"},inplace=True)
del uselog_months["usedate"]
uselog_months

image.png

ノック25.py
uselog_customer=uselog_months.groupby("customer_id").agg(["mean","me
dian","max","min"])["count"]#平均値、中央値、最大値、最小値
uselog_customer=uselog_customer.reset_index(drop=False)
uselog_customer

image.png

注意!
drop=Trueにしたらどうなる?

ノック25.py
uselog_customer=uselog_months.groupby("customer_id").agg(["mean","me
dian","max","min"])["count"]#平均値、中央値、最大値、最小値
uselog_customer=uselog_customer.reset_index(drop=False)
uselog_customer

image.png

ノック26:利用履歴データから定期利用フラグ作成

ノック26.py
#年月だけでなく曜日も特定する
uselog["weekday"]=uselog["usedate"].dt.weekdayy#0月曜、1火曜、2水曜、3木曜、4金曜、5土曜、6日曜
uselog_weekday=uselog.groupby(["customer_id","年月","weekday"],as_index=False).count()[["customer_id","年月","weekday","log_id"]]
uselog_weekday.rename(columns={"log_id":"count"},inplace=True) #inplaceは元のデータを更新するか否か(Trueの時更新)
uselog_weekday.head()

image.png

ノック26.py
uselog_weekday=uselog_weekday.groupby("customer_id",as_index=False).max()[["customer_id","count"]]
uselog_weekday["routine_flg"]=0
uselog_weekday["routine_flg"]=uselog_weekday["routine_flg"].where(uselog_weekday["count"]<4,1)
uselog_weekday.head()

image.png

ノック27:顧客データと利用履歴データを結合

ノック27.py
#customer_joinとuselog_customerを合体、customer_joinとuselog_weekdayを合体
customer_join=pd.merge(customer_join,uselog_customer,on="customer_id",how="left")
customer_join=pd.merge(customer_join,uselog_weekday[["customer_id","routine_flg"]],on="customer_id",how="left")
customer_join.head()

image.png
medianやroutine_flgがカラム列に加わった!

ノック27.py
customer_join.isnull().sum()

image.png

ノック28:会員期間を計算

ノック28.py
from dateutil.relativedelta import relativedelta
customer_join["calc_date"]=customer_join["end_date"]
customer_join["calc_date"]=customer_join["calc_date"].fillna(pd.to_datetime("20190430"))
customer_join["membership_period"]=0
for i in range(len(customer_join)):
  delta=relativedelta(customer_join["calc_date"].iloc[i],customer_join["start_date"].iloc[i])
  customer_join["membership_period"].iloc[i]=delta.years*12+delta.months
customer_join.head()

image.png

ノック29:顧客行動の各種統計量を把握

ノック29.py
customer_join[["mean","median","max","min"]].describe()

image.png

ノック29.py
customer_join.groupby("routine_flg").count()["customer_id"]

image.png

ノック29.py
import matplotlib.pyplot as plt
%matplotlib inline
plt.hist(customer_join["membership_period"])

image.png

ノック30:大会ユーザーと継続ユーザーの違いを把握

ノック30.py
customer_end=customer_join.loc[customer_join["is_deleted"]==1]
customer_end.describe()

image.png

ノック30.py
customer_stay=customer_join.loc[customer_join["is_deleted"]==0]
customer_stay.describe()

image.png

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0