はじめに
deepblueインターン生の中山です。
PythonとRを交互に書く時に毎回迷うので、備忘録のblogとして残そうと思います。
今回は基本的なデータフレームの簡単な操作についてまとめようと思います。
連載
- 下記5記事のまとめ:PythonのpandasとRのdplyrを用いたデータフレーム操作比較
- 【読み込み、要約統計量、行・列選択、代入】PythonとRのデータフレーム操作比較 vol.1
- 【列追加、重複削除、列名変更、結合、マージ、集約】PythonとRのデータフレーム操作比較 vol.2
- 【集計、ソート、縦持ち・横持ち変換】PythonとRのデータフレーム操作比較 vol.3
- 【列分割・NA操作・サンプリング】PythonとRのデータフレーム操作比較 vol.4
- 【train/test分割】PythonとRのデータフレーム操作比較 vol.5
利用したデータ
今回使用したデータは、MineThatData E-Mail Analytics And Data Mining Challenge datasetです。
効果検証入門内で解析されているデータセットです。
データの詳細は今回は重要ではないので割愛しますが、興味のある方はWEBサイトからデータを確認してみてください。
簡単な操作
コードの具体的な説明をする前に、PythonとRで異なる表記やショートカットの差異について記述致します。
ここでは、Windowsの場合を想定しております。
Python (Jupyter Notebook)
- 代入:
=
- コメントアウト:
ctrl + /
- やり直し:
ctrl + y
R (Rstudio)
- 代入:
<-
- コメントアウト:
shift + ctrl + c
- やり直し:
shift + ctrl + z
- パイプ演算子(
%>%
):shift + ctrl + m
データ読み込み
csvデータを読み込んで、データフレームを確認するコード。
Python
pd.read_csv()
import pandas as pd
PATH = "http://www.minethatdata.com/Kevin_Hillstrom_MineThatData_E-MailAnalytics_DataMiningChallenge_2008.03.20.csv"
df = pd.read_csv(PATH)
df.head()
# recency history_segment history mens womens zip_code newbie channel segment visit conversion spend
# 0 10 2) $100 - $200 142.44 1 0 Surburban 0 Phone Womens E-Mail 0 0 0
# 1 6 3) $200 - $350 329.08 1 1 Rural 1 Web No E-Mail 0 0 0
# 2 7 2) $100 - $200 180.65 0 1 Surburban 1 Web Womens E-Mail 0 0 0
# 3 9 5) $500 - $750 675.83 1 0 Rural 1 Web Mens E-Mail 0 0 0
# 4 2 1) $0 - $100 45.34 1 0 Urban 0 Web Womens E-Mail 0 0 0
R
read.csv()
PATH <- "http://www.minethatdata.com/Kevin_Hillstrom_MineThatData_E-MailAnalytics_DataMiningChallenge_2008.03.20.csv"
df <- read.csv(PATH)
head(df)
# recency history_segment history mens womens zip_code newbie channel segment visit conversion spend
# 1 10 2) $100 - $200 142.44 1 0 Surburban 0 Phone Womens E-Mail 0 0 0
# 2 6 3) $200 - $350 329.08 1 1 Rural 1 Web No E-Mail 0 0 0
# 3 7 2) $100 - $200 180.65 0 1 Surburban 1 Web Womens E-Mail 0 0 0
# 4 9 5) $500 - $750 675.83 1 0 Rural 1 Web Mens E-Mail 0 0 0
# 5 2 1) $0 - $100 45.34 1 0 Urban 0 Web Womens E-Mail 0 0 0
# 6 6 2) $100 - $200 134.83 0 1 Surburban 0 Phone Womens E-Mail 1 0 0
行数・列数の確認
データの行数、列数を確認するコード。
Python
- 行数 x 列数:
shape
- 行数:
shape[0]
- 列数:
shape[1]
df.shape
# (64000, 12)
df.shape[0]
# 64000
df.shape[1]
# 12
R
- 行数 x 列数:
dim()
- 行数:
nrow()
- 列数:
ncol()
df %>% dim()
# dim(df)# こちらでも可
# [1] 64000 12
df %>% nrow()
# nrow(df)# こちらでも可
# [1] 64000
df %>% ncol()
# ncol(df)# こちらでも可
# [1] 12
型の確認
データ各列の型を確認するコード。
Rだとstr
で表すため、文字列と間違えないよう注意が必要です。
Python
dtypes
df.dtypes
# recency int64
# history_segment object
# history float64
# mens int64
# womens int64
# zip_code object
# newbie int64
# channel object
# segment object
# visit int64
# conversion int64
# spend float64
# dtype: object
R
str()
df %>% str()
# str(df)# こちらでも可
# 'data.frame': 64000 obs. of 12 variables:
# $ recency : int 10 6 7 9 2 6 9 9 9 10 ...
# $ history_segment: Factor w/ 7 levels "1) $0 - $100",..: 2 3 2 5 1 2 3 1 5 1 ...
# $ history : num 142.4 329.1 180.7 675.8 45.3 ...
# $ mens : int 1 1 0 1 1 0 1 0 1 0 ...
# $ womens : int 0 1 1 0 0 1 0 1 1 1 ...
# $ zip_code : Factor w/ 3 levels "Rural","Surburban",..: 2 1 2 1 3 2 2 3 1 3 ...
# $ newbie : int 0 1 1 1 0 0 1 0 1 1 ...
# $ channel : Factor w/ 3 levels "Multichannel",..: 2 3 3 3 3 2 2 2 2 3 ...
# $ segment : Factor w/ 3 levels "Mens E-Mail",..: 3 2 3 1 3 3 3 3 1 3 ...
# $ visit : int 0 0 0 0 0 1 0 0 0 0 ...
# $ conversion : int 0 0 0 0 0 0 0 0 0 0 ...
# $ spend : num 0 0 0 0 0 0 0 0 0 0 ...
要約統計量
データフレーム各列の要約統計量などを取得するコード。
Rはsummary
を使うことで、質的変数(主にfactor型)にも適用可能です。
Python
describe()
df.describe()
# recency history mens womens newbie visit conversion spend
# count 64000.000000 64000.000000 64000.000000 64000.000000 64000.000000 64000.000000 64000.000000 64000.000000
# mean 5.763734 242.085656 0.551031 0.549719 0.502250 0.146781 0.009031 1.050908
# std 3.507592 256.158608 0.497393 0.497526 0.499999 0.353890 0.094604 15.036448
# min 1.000000 29.990000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
# 25% 2.000000 64.660000 0.000000 0.000000 0.000000 0.000000 0.000000 0.000000
# 50% 6.000000 158.110000 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000
# 75% 9.000000 325.657500 1.000000 1.000000 1.000000 0.000000 0.000000 0.000000
# max 12.000000 3345.930000 1.000000 1.000000 1.000000 1.000000 1.000000 499.000000
R
summary()
df %>% summary()
# summary(df)# こちらでも可
# recency history_segment history mens womens zip_code
# Min. : 1.000 1) $0 - $100 :22970 Min. : 29.99 Min. :0.000 Min. :0.0000 Rural : 9563
# 1st Qu.: 2.000 2) $100 - $200 :14254 1st Qu.: 64.66 1st Qu.:0.000 1st Qu.:0.0000 Surburban:28776
# Median : 6.000 3) $200 - $350 :12289 Median : 158.11 Median :1.000 Median :1.0000 Urban :25661
# Mean : 5.764 4) $350 - $500 : 6409 Mean : 242.09 Mean :0.551 Mean :0.5497
# 3rd Qu.: 9.000 5) $500 - $750 : 4911 3rd Qu.: 325.66 3rd Qu.:1.000 3rd Qu.:1.0000
# Max. :12.000 6) $750 - $1,000: 1859 Max. :3345.93 Max. :1.000 Max. :1.0000
# 7) $1,000 + : 1308
#
# newbie channel segment visit conversion
# Min. :0.0000 Multichannel: 7762 Mens E-Mail :21307 Min. :0.0000 Min. :0.000000
# 1st Qu.:0.0000 Phone :28021 No E-Mail :21306 1st Qu.:0.0000 1st Qu.:0.000000
# Median :1.0000 Web :28217 Womens E-Mail:21387 Median :0.0000 Median :0.000000
# Mean :0.5022 Mean :0.1468 Mean :0.009031
# 3rd Qu.:1.0000 3rd Qu.:0.0000 3rd Qu.:0.000000
# Max. :1.0000 Max. :1.0000 Max. :1.000000
#
# spend
# Min. : 0.000
# 1st Qu.: 0.000
# Median : 0.000
# Mean : 1.051
# 3rd Qu.: 0.000
# Max. :499.000
番号指定
PythonとRは、数字で指定を行う時に違いがあるため、その差異について示します。
また、同じデータを表示するコードをPythonとRで示します。
Python
- 最初の番号:0番
[a:b]
のa
:含む[a:b]
のb
:含まない
df.iloc[0:5,1:4]
# history_segment history mens
# 0 2) $100 - $200 142.44 1
# 1 3) $200 - $350 329.08 1
# 2 2) $100 - $200 180.65 0
# 3 5) $500 - $750 675.83 1
# 4 1) $0 - $100 45.34 1
R
- 最初の番号:1番
[a:b]
のa
:含む[a:b]
のb
:含む
df[1:5,2:4]
# history_segment history mens
# 1 2) $100 - $200 142.44 1
# 2 3) $200 - $350 329.08 1
# 3 2) $100 - $200 180.65 0
# 4 5) $500 - $750 675.83 1
# 5 1) $0 - $100 45.34 1
列の選択
読み込んだデータフレームにおいて、特定の列を選択するコード。
また、Rではtidyverse
を用いない場合のコードも載せています。
Python
[["hoge", "fuga"]]
loc[:,["hoge", "fuga"]]
df_new = df[["recency", "history", "zip_code"]]
df_new = df.loc[:, ["recency", "history", "zip_code"]]
# df_new.head()
# recency history zip_code
# 0 10 142.44 Surburban
# 1 6 329.08 Rural
# 2 7 180.65 Surburban
# 3 9 675.83 Rural
# 4 2 45.34 Urban
R
select(hoge, fuga)
# tidyverseの場合
df_new <- df %>%
select(recency, history, zip_code)
# tidyverseを利用しない場合
# df_new <- df[c("recency", "history", "zip_code")]
# df_new %>% head()
# recency history zip_code
# 1 10 142.44 Surburban
# 2 6 329.08 Rural
# 3 7 180.65 Surburban
# 4 9 675.83 Rural
# 5 2 45.34 Urban
# 6 6 134.83 Surburban
行の抽出
データフレームから、条件に合致するデータを抽出するコード。
今回はhistory > 3000
とchannel == "Phone"
の2つの条件を設定しております。
Python
[(hoge > a) & (fuga == b)]
df_new = df[(df.history > 3000) & (df.channel == "Phone")]
# df_new
# recency history_segment history mens womens zip_code newbie channel segment visit conversion spend
# 4579 2 7) $1,000 + 3345.93 1 1 Surburban 1 Phone No E-Mail 0 0 0.0
# 43060 1 7) $1,000 + 3003.48 1 1 Urban 1 Phone No E-Mail 0 0 0.0
R
filter(hoge > a, fuga == b)
# tidyverseの場合
df_new <- df %>%
filter(history > 3000,
channel == "Phone")
# tidyverseを利用しない場合
# df_new <- df[df$history > 3000 & df$channel == "Phone",]
# df_new
# recency history_segment history mens womens zip_code newbie channel segment visit conversion spend
# 1 2 7) $1,000 + 3345.93 1 1 Surburban 1 Phone No E-Mail 0 0 0
# 2 1 7) $1,000 + 3003.48 1 1 Urban 1 Phone No E-Mail 0 0 0
データ代入
条件に合致するとき、特定の列に値を代入するコード。
ここでは、spend
の列に1000
を代入しています。
※history > 3000
の条件はデータを確認しやすくするためで、特に意味はないです。
Python
assign(hoge = a)
df_new = df[df.history > 3000].assign(spend = 1000)
# df_new
# recency history_segment history mens womens zip_code newbie channel segment visit conversion spend
# 4579 2 7) $1,000 + 3345.93 1 1 Surburban 1 Phone No E-Mail 0 0 1000
# 38680 1 7) $1,000 + 3215.97 1 1 Urban 1 Multichannel Mens E-Mail 1 0 1000
# 43060 1 7) $1,000 + 3003.48 1 1 Urban 1 Phone No E-Mail 0 0 1000
# 52860 1 7) $1,000 + 3040.20 0 1 Urban 1 Web Womens E-Mail 0 0 1000
R
mutate(hoge = a)
# tidyverseの場合
df_new <- df %>%
filter(history > 3000) %>%
mutate(spend = 1000)
# tidyverseを利用しない場合
# df[df$history > 3000, "spend"] <- 1000
# df_new
# recency history_segment history mens womens zip_code newbie channel segment visit conversion spend
# 1 2 7) $1,000 + 3345.93 1 1 Surburban 1 Phone No E-Mail 0 0 1000
# 2 1 7) $1,000 + 3215.97 1 1 Urban 1 Multichannel Mens E-Mail 1 0 1000
# 3 1 7) $1,000 + 3003.48 1 1 Urban 1 Phone No E-Mail 0 0 1000
# 4 1 7) $1,000 + 3040.20 0 1 Urban 1 Web Womens E-Mail 0 0 1000