Rユーザー向け Pythonデータ処理入門


## はじめに　
  
### こんな人向け
・Rは分かるけど, Pythonは分からないという人向け.  

### 背景
・R初心者（初稿投稿時: R歴7ヶ月）.
・最近Pythonにも手を出してみるも, 単純なデータ処理すら書き方がRと異なるため難しい.
・RとPythonのデータ処理の対応表を見たい.
・いくつか参考サイトあるが, 自分が必要とするものが完全に揃っているわけではない.
　＝＞[R vs Python：データ解析を比較](http://postd.cc/r-vs-python-head-to-head-data-analysis/)
・じゃあ自分用メモを作っちゃおう.


## 参考にしたサイト

<br>

- 【Python】  
 - [Python Pandasでのデータ操作の初歩まとめ − 前半：データ作成＆操作編](https://qiita.com/hik0107/items/d991cc44c2d1778bb82e)    
 - [ゆるふわPandasチートシート](https://qiita.com/tanemaki/items/2ed05e258ef4c9e6caac)    
 - [『Pythonによるデータ分析入門』](https://www.oreilly.co.jp/books/9784873116556/)    
 - [Python文字列操作マスター](https://qiita.com/tomotaka_ito/items/594ee1396cf982ba9887)    
 - [pandasの使い方（merge、join、concat編）](http://pppurple.hatenablog.com/entry/2016/06/27/022310)    

<br>

- 【R】  
 - [dplyrを使いこなす！基礎編](https://qiita.com/matsuou1/items/e995da273e3108e2338e)    
 - [stringr — Rの文字列をまともな方法で処理する](https://heavywatal.github.io/rstats/stringr.html)    
 - [readr — 高速で柔軟なテーブル読み込み](https://heavywatal.github.io/rstats/readr.html)    

<br>

## 基本操作（base）  

・irisデータセットを使用.
・ちょこちょこ余計な操作もしています.  

### 行・列数を確認

```r:R
dim(iris)
```

```py:py
iris.shape
```

### 行数を確認

```r:R
nrow(iris)
```

```py:py
len(iris)
```

### 列数を確認

```r:R
ncol(iris)
```

```py:py
len(iris.columns)
```

### データ型確認

```r:R
class(iris)
```
```r:R
class(iris$Sepal.Length)
```

```py:py
type(iris)
```
```py:py
type(iris.Species)
```

### 先頭のn行を確認

```r:R
head(iris)
```
```py:py
iris.head()
```

### 列名を確認

```r:R
names(iris)
```
```py:py
iris.columns
```

### 指定行の取り出し

```r:R
iris[1,]
```
```py:py
iris.iloc[0] # 行番号を使って行抽出
```


### 指定列の取り出し

```r:R
head(iris[,1])
```
```py:py
iris["Sepal.Length"].head()
```


### 行結合

```r:R
iris2 = iris
dim(rbind(iris, iris2))
```
```py:py
iris2 = iris
pd.concat([iris, iris2],axis=0).shape # axis=0は省略可能
```

### 列結合

```r:R
iris2 = iris
head(cbind(iris, iris2))
```
```py:py
iris2 = iris
pd.concat([iris, iris2],axis=1).head() # axis=1は省略不可
```


### 文字列型ー＞数値型
```r:R
c = "1"
class(as.numeric(c))
```
```py:py
c = "1"
type(float(c))
```


### 数値型ー＞文字列型
```r:R
v = 1
class(as.character(v))
```
```py:py
f = 1
type(str(f))
```


### 統計要約量

```r:R
summary(iris)
```
```py:py
iris.describe()
# 件数、平均、標準偏差、最小値、最大値、中央値、四分位数
```


### 欠損値を含む行を削除

```r:R
iris.na <- iris %>% mutate(column.na=seq(1:nrow(iris))) #nrow()は行数を返す。seqは順に任意の数(デフォルト1)ずつ増減する数列を返す。
iris.na[1,6] <- NA # "<-" は代入記号
head(na.omit(iris.na))
```
```py:py
series = pd.Series(range(150), index=new_iris.index) #index付きのシリーズ作成。indexは元のdfのindex(=行番号)
del series[0] # 要素の削除(del文, popメソッド, removeメソッド) https://www.pythonweb.jp/tutorial/list/index8.html
iris_na = iris
iris_na["column_na"] = series
iris_na.dropna(axis=0).head()
```


<br>

## データ操作（dplyr）


### rename
```r:R
new_colnames <- stringr::str_replace(colnames(iris), "[.]", "_") # "."を"_"に変換する
new_iris <- iris
colnames(new_iris) <- new_colnames
# df %>% rename(new_colname = old_colname) とすることもできる。
names(new_iris)
```
```py:py
rename_dict = {column: column.replace('.', '_') for column in iris.columns} # 列名の"."を"_"に書き換える
new_iris = iris.rename(columns=rename_dict)
new_iris.columns
```


### filter

```r:R
head(iris %>% filter(Sepal.Length > 6.4))
```
```py:py
new_iris[(new_iris['Sepal_Length'] > 5) & (new_iris['Sepal_Width'] > 3)].head()
# データフレーム[Booleanの配列を入れる]
# 複数条件の場合は、or条件の "|" もしくは and条件の "&"を間に入れ、それぞれの条件を()で囲む
```


### select

- 列名で列選択  

```r:R
head(iris %>% select(Sepal.Length))
```
```py:py
new_iris[["Sepal_Length", "Petal_Length"]].head() # 複数列選択（[]で[列名,列名]を囲む）  
```

- 列番号で列選択

```r:R
head(iris %>% select(-1))
```
```py:py
new_iris.drop('Species', axis=1).head(6) # 列削除
```


### mutate

```r:R
head(iris %>% mutate(new.column="new value"))
```
```py:py
series = pd.Series("new_value", index=new_iris.index) # index付きのシリーズ作成。indexは元のdfのindex(=行番号)
new_iris["new_column"]=series
new_iris.head()
```


### arrange

- デフォルトでは昇順  

```r:R
head(iris %>% arrange(Sepal.Length))
```
```py:py
new_iris.sort_values(by=['Sepal_Length', 'Sepal_Width']).head() # 複数の値で昇順でソート
```

- desc()で降順にもできる

```r:R
head(iris %>% arrange(desc(Sepal.Length)))
```
```py:py
new_iris.sort_values(by='Sepal_Length', ascending=False).head() # 降順でソート
```


### group_by

```r:R
head(
knitr::kable(iris %>% 
       arrange(Sepal.Width) %>% 
       group_by(Species) %>% 
       mutate(mean.S.L.by.Species=mean(Sepal.Width)))
)
```
```py:py
new_iris_grouped = new_iris.groupby("Species")  # SpeciesでGroup_byを行う。
new_iris_grouped[["Sepal_Length","Sepal_Width"]].mean()          
  # Group化されたされたオブジェクトに対してMeanを行う。
  # 必要であれば、Meanを行う変数を指定できる。
```


### summarise

```r:R
head(iris %>% summarise(max.sl=max(Sepal.Length), 
                        max.sw=max(Sepal.Width), 
                        min.pl=min(Petal.Length), 
                        mean.pw=mean(Petal.Width)))
```
```py:py
# 同上
new_iris_grouped = new_iris.groupby("Species")  # SpeciesでGroup_byを行う。
new_iris_grouped[["Sepal_Length","Sepal_Width"]].mean()          
  # Group化されたされたオブジェクトに対してMeanを行う。
  # 必要であれば、Meanを行う変数を指定できる。
```



### join

```r:R
colnames_for_join <- stringr::str_replace(colnames(iris), "th", "th_for_join") # 列名の"*th"を"*th_for_join"に書き換える
iris_for_join <- iris 
colnames(iris_for_join) <- colnames_for_join
iris %>% left_join(iris_for_join, by="Species")
```
```py:py
dict_for_join = {column: column.replace('th', 'th_for_join') for column in new_iris.columns}
iris_for_join = new_iris
iris_for_join = iris_for_join.rename(columns=dict_for_join)
pd.merge(new_iris, iris_for_join, how='left')
```

<br>

## 文字列処理（stringr）

### データ読み込み

```r:R
species <- iris$Species
species[1]
```
```py:py
species = new_iris["Species"]
species[0]
```


### str_length: 文字列の長さを返す.

```r:R
str_length(species[1])
```
```py:py
len(species[0])
```


### str_sub: 文字列の一部抽出する.

```r:R
str_sub(species[1], start = 1, end = 4)
```
```r:R
str_sub(species[1], start = -4, end = -1)
```
```py:py
species[0][0:2]
```
```py:py
species[0][-2:]
```


### str_detect: 特定のパターンを文字列が含むかどうか判別する.

```r:R
str_detect(species[1], "eto")
```
```py:py
"eto" in species[0]
```


### str_subset: 特定のパターンを含む文字列を抽出する.

```r:R
str_subset(species, "set")
```
```py:py
for index in range(1,len(species)): 
    if ("set" in species[index]) ==True:
        print(species[index])
```


### str_locate: 特定のパターンが文字列の何番目に位置するかを返す.

```r:R
str_locate(species[1], "set")
```
```py:py
species[0].find("t")
```


### str_replace: 文字列内の特定のパターンを置換する.

```r:R
str_replace(species[1], "sa", "sa_replaced")
```
```py:py
species[0].replace("sa", "sa_replaced")
```


### str_trim: 文字列の空白を除去する.

```r:R
species_trim <- c(" species ")
str_trim(species_trim, side="both")
```
```py:py
species_trim = (" species ")
species_trim.strip()
# lstripはstripと同等の処理を左端のみに適用
# rstripはstripと同等の処理を右端のみに適用
```


<br>

## その他

### readr::parse_number: 数字のみを抽出する.

```r:R
x <- c("6e23")
parse_number(x)
```
```py:py
import re
x = ("6e23")
re.match("\d", x).group()
```