RをPandasに置き換える(ヒストグラム)
ビジネス活用事例で学ぶ データサイエンス入門
タイトルのとおり、ビジネス事例(アプリ開発会社の事例)を元にしてデータ分析を学ぶスタイルになっています。馴染みのある事例なのでデータ活用のイメージがしやすい内容になっています。
本書はRを使っていますが、どちらかというとPython Pandasの方が好きなので、RからPandasに置き換えてみました。
(0)R・データの準備
Rインストール
R-3.2.3.pkgをインストールしました。
データダウンロード
上記からダウンロードしました。
(1)CSVファイル読み込み
- DAU(1日1回以上アクセスしたユーザのデータ
- DPU(1日1円以上課金したユーザのデータ
- Install(ユーザごとにいつゲームを利用開始したかのデータ)
R
> dau <- read.csv("section3-dau.csv", header = T, stringsAsFactors = F) > head(dau) log_date app_name user_id 1 2013-06-01 game-01 116 2 2013-06-01 game-01 13491 3 2013-06-01 game-01 7006 > dpu <- read.csv("section3-dpu.csv", header = T, stringsAsFactors = F) > head(dpu) log_date app_name user_id payment 1 2013-06-01 game-01 351 1333 2 2013-06-01 game-01 12796 81 3 2013-06-01 game-01 364 571 > install <- read.csv("section3-install.csv", header = T, stringsAsFactors= F) > head(install) install_date app_name user_id 1 2013-04-15 game-01 1 2 2013-04-15 game-01 2 3 2013-04-15 game-01 3
Pandas
>>> import pandas as pd >>> dau = pd.read_csv("section3-dau.csv") >>> dau log_date app_name user_id 0 2013-06-01 game-01 116 1 2013-06-01 game-01 13491 2 2013-06-01 game-01 7006 >>> dpu = pd.read_csv("section3-dpu.csv") >>> dpu log_date app_name user_id payment 0 2013-06-01 game-01 351 1333 1 2013-06-01 game-01 12796 81 2 2013-06-01 game-01 364 571 >>> install = pd.read_csv("section3-install.csv") >>> install install_date app_name user_id 0 2013-04-15 game-01 1 1 2013-04-15 game-01 2 2 2013-04-15 game-01 3
(2)DAUのデータにInstallデータをくっつける
R
> dau.install <- merge(dau, install, by = c("user_id", "app_name")) > head(dau.install) user_id app_name log_date install_date 1 1 game-01 2013-06-03 2013-04-15 2 1 game-01 2013-06-14 2013-04-15 3 1 game-01 2013-07-09 2013-04-15
Pandas
>>> dauinstall = pd.merge(dau, install, how='left', on=['user_id', 'app_name']) >>> dauinstall log_date app_name user_id install_date 0 2013-06-01 game-01 116 2013-04-17 1 2013-06-01 game-01 13491 2013-06-01 2 2013-06-01 game-01 7006 2013-05-03
(3)dau.installに、さらにDPUデータをくっつける
R
> dau.install.payment <- merge(dau.install, dpu, by = c("log_date", "app_name", "user_id"), all.x = T) > head(dau.install.payment) log_date app_name user_id install_date payment 1 2013-06-01 game-01 1 2013-04-15 NA 2 2013-06-01 game-01 3 2013-04-15 NA 3 2013-06-01 game-01 6 2013-04-15 NA
Pandas
>>> dauinstallpayment = pd.merge(dauinstall, dpu, how = 'left', on = ['log_date', 'app_name', 'user_id']) >>> dauinstallpayment log_date app_nam user_id install_date payment 0 2013-06-01 game-01 116 2013-04-17 NaN 1 2013-06-01 game-01 13491 2013-06-01 NaN 2 2013-06-01 game-01 7006 2013-05-03 NaN
(4)payment=NAのデータを除外する
R
> head(na.omit(dau.install.payment)) log_date app_name user_id install_date payment 7 2013-06-01 game-01 19 2013-04-15 162 81 2013-06-01 game-01 351 2013-04-18 1333 84 2013-06-01 game-01 364 2013-04-18 571
Pandas
>>> dauinstallpayment.dropna(subset=['payment']) log_date app_name user_id install_date payment 12 2013-06-01 game-01 19 2013-04-15 162 84 2013-06-01 game-01 351 2013-04-18 1333 87 2013-06-01 game-01 364 2013-04-18 571
(5)payment=NAのデータに課金額0を設定する
R
> dau.install.payment$payment[is.na(dau.install.payment$payment)] <- 0 > head(dau.install.payment) log_date app_name user_id install_date payment 1 2013-06-01 game-01 1 2013-04-15 0 2 2013-06-01 game-01 3 2013-04-15 0 3 2013-06-01 game-01 6 2013-04-15 0
Pandas
>>> dauinstallpayment.fillna(0) log_date app_name user_id install_date payment 0 2013-06-01 game-01 116 2013-04-17 0 1 2013-06-01 game-01 13491 2013-06-01 0 2 2013-06-01 game-01 7006 2013-05-03 0 >>> dauinstallpayment.fillna(0, inplace=True) >>> dauinstallpayment log_date app_name user_id install_date payment 0 2013-06-01 game-01 116 2013-04-17 0 1 2013-06-01 game-01 13491 2013-06-01 0 2 2013-06-01 game-01 7006 2013-05-03 0
(6)月次で集計する
R
> dau.install.payment$log_month <- substr(dau.install.payment$log_date, 1, 7) > dau.install.payment$install_month <- substr(dau.install.payment$install_date, 1, 7) > library("plyr") > mau.payment <- ddply(dau.install.payment, .(log_month, user_id, install_month), summarize, payment = sum(payment)) > head(mau.payment) log_month user_id install_month payment 1 2013-06 1 2013-04 0 2 2013-06 2 2013-04 0 3 2013-06 3 2013-04 14994
Pandas
dauinstallpayment['log_month'] = dauinstallpayment['log_date'].str[0:7] dauinstallpayment['install_month'] = dauinstallpayment['install_date'].str[0:7] >>> maupayment = dauinstallpayment.groupby(['user_id','log_month', 'install_month'])['payment'].sum() >>> maupayment user_id log_month install_month 1 2013-06 2013-04 0 2013-07 2013-04 0 2 2013-06 2013-04 0 3 2013-06 2013-04 14994
(7)新規ユーザか既存ユーザかの区分を追加する
R
> mau.payment$user.type <-ifelse(mau.payment$install_month == mau.payment$log_month, "install", "existing") > mau.payment.summary <- ddply(mau.payment, .(log_month, user.type), summarise, total.payment = sum(payment)) > head(mau.payment) log_month user_id install_month payment user.type 1 2013-06 1 2013-04 0 existing 2 2013-06 2 2013-04 0 existing 3 2013-06 3 2013-04 14994 existing 4 2013-06 4 2013-04 0 existing 5 2013-06 6 2013-04 0 existing 6 2013-06 7 2013-04 0 existing > head(mau.payment.summary) log_month user.type total.payment 1 2013-06 existing 177886 2 2013-06 install 49837 3 2013-07 existing 177886 4 2013-07 install 29199
Pandas
>>> dauinstallpayment['user_type'] = np.where(dauinstallpayment['log_month'] == dauinstallpayment['install_month'], 'install', 'existing') >>> dauinstallpayment log_date app_name user_id install_date payment log_month install_month user_type 0 2013-06-01 game-01 116 2013-04-17 0 2013-06 2013-04 existing 1 2013-06-01 game-01 13491 2013-06-01 0 2013-06 2013-06 install 2 2013-06-01 game-01 7006 2013-05-03 0 2013-06 2013-05 existing
(8)グラフによりデータを可視化する(新規、既存比較)
R
ggplot(mau.payment.summary, aes(x = log_month, y = total.payment, fill = user.type)) + geom_bar(stat="identity") + scale_y_continuous(label = comma)
Pandas
TODO..
(9)グラフによりデータを可視化する(金額別売上比較)
R
ggplot(mau.payment[mau.payment$payment > 0 & mau.payment$user.type == "install", ], aes(x = payment, fill = log_month)) + geom_histogram(position = "dodge", binwidth = 2000)
Pandas
TODO..
補足 Pandasを0.17にした
Equivalent of R/ifelse in Python/Pandas? Compare string columns?
conda update anaconda conda update conda conda update pandas numpy: 1.9.2-py34_0 --> 1.10.4-py34_0 pandas: 0.16.2-np19py34_0 --> 0.17.1-np110py34_0 pytz: 2015.4-py34_0 --> 2015.7-py34_0 six: 1.9.0-py34_0 --> 1.10.0-py34_0
まとめ
Rの良いところの感想は以下です。しばらくRとPandasを併用してみてPro/Conを考えてみます。いずれにしても両方知っておくと、情報量を増やすことができるので良いと思いました。
- Rのインストールが簡単
- グラフがmatplotlibより(少し)オシャレ
参考
Python pandas 図でみる データ連結 / 結合処理
Equivalent of transform in R/ddply in Python/pandas?
Equivalent of R/ifelse in Python/Pandas? Compare string columns?