Pandas 早見表！

# はじめに

最近機械学習をはじめました！
必須ライブラリであるPandas,numpy,matplotlibの使い方を覚えるのが大変ですね。。。
なのでPandasの使い方早見表を作成しました！

* 前半：機能一覧のグラフ
* 後半：前半に紹介した機能の実際の使用例

をまとめました。

各機能の細かいところ(引数とか)には触れません！

機械学習を行う際によく使用する用法なので、初心者の方は目を通してPandasでできることをイメージしてみてください。
中級者以上の方は「あれってPandasでどうやるんだっけ?」というときに使っていただければ幸いですm(_ _)m


# 機能一覧

## 1.データ読み込み/書き込み編

|Action|Syntax|
|:---------|:-----------------|
|CSVファイルをリストに読み込み|sample = pd.read_csv('sample.csv')|
|リストをCSVファイルに書き込み|sample.to_csv('sample2.csv')|
|excelファイルをリストに読み込み|sample = pd.read_excel('sample.xlsx')|
|リストをexcelファイルに書き込み|sample.to_excel('sample2.xlsx')|

## 2.データ分析編

* "sample"が分析対象データのDataFrameです
* import pandas as pdを実行していることを前提としています

|Action|Syntax|
|:-----|:-----|
|先頭数行を表示|sample.head()|
|末尾数行を表示|sample.tail()|
|ソートして表示|sample.sort_values(by=['特徴量'], ascending=True)|
|特徴量の種類と数を表示|sample.shape|
|特徴量の種類数を表示|sample.nunique()|
|特徴量の種類を一覧で表示|sample['特徴量'].drop_duplicates()|
|インデックス情報を表示|sample.index|
|カラム(ヘッダ)を表示|sample.columns|
|欠損値の有無を確認|sample.isnull().sum()|
|該当特徴量の平均値|sample['特徴量'].mean()|
|該当特徴量における値の出現回数|sample['特徴量'].value_counts()|
|該当特徴量における条件を満たすデータのみ表示|sample[sample['特徴量'] <条件式> ]|
|基礎統計量を表示|sample.describe()|
|ヒストグラムを表示|sample['特徴量'].hist(bins=<グラフの棒の数>)|
|クロス集計する|pd.crosstab(sample['特徴量1'],sample['特徴量2'])|
|割合をクロス集計で表示|pd.crosstab(sample['特徴量1'],sample['特徴量2']).apply(lambda x: x/x.sum(), axis=1)|
|相関を表示|sample.corr()|
|散布図グラフを表示|pd.plotting.scatter_matrix(sample)|

## 3.データ加工編
|Action|Syntax|
|:-----|:-----|
|行を削除|sample2 = sample.drop(行番号,axis=0)|
|列を削除|sample2 = sample.drop('列のヘッダー名',axis=1)|
|複製を作成|sample.copy()|
|該当特徴量を抽出|sample2 = sample[['特徴量1','特徴量2',.....]]|
|特徴量同士を計算して新しい特徴量を作成|sample['新特徴量'] = sample['特徴量1'] <演算子> sample['特徴量2']|
|該当特徴量に対して関数を適用して新特徴量を作成|sample['新特徴量'].apply( lambda x : <関数 or 式> )|
|欠損値があるデータを削除|sample.dropna()|
|欠損値を補完|sample.fillna(value=<補完値>)|
|被っているデータを削除|sample.drop_duplicates()|

# 使用例

ここではSIGNATEの練習問題データを例として使用します。
[お弁当の需要予測](https://signate.jp/competitions/24/data)


## 1.データ読み込み/書き込み編

```
import pandas as pd

sample = pd.read_csv('train.csv')
```

これ以外は割愛させていただきます。。。

## 2.データ分析編

##### 先頭数行を表示 <font color="DarkGray">*sample.head()*</font>

```
sample.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/af0c16b5-8c40-2ca0-bcc5-bbd3e7efa273.png)

引数に数値を渡すことで、表示する行数を調整することが可能です。
(デフォルト5行)

##### 末尾数行を表示 <font color="DarkGray">*sample.tail()*</font>

```
sample.tail()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/24a2b6a4-b23d-ce3a-c37b-55e94eaaff83.png)


引数に数値を渡すことで、表示する行数を調整することが可能です。
(デフォルト5行)

##### ソートして表示 <font color="DarkGray">*sample.sort_values(by=['特徴量'], ascending=True)*</font>

```
# kcalでソート
sample.sort_values(by=['kcal'], ascending=True)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/4f875631-0d56-622e-7eff-3b5723efda28.png)

ascending=Falseにすると降順でソートされる

##### 特徴量の種類と数を表示 <font color="DarkGray">*sample.shape*</font>

```
# ()を付けないように注意してください
sample.shape
```


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/ab17b87b-9f26-b468-3738-ad3d00e7fd63.png)


##### 特徴量の種類数を表示 <font color="DarkGray">*sample.nunique()*</font>

```
sample.nunique()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/da0746fe-fe76-f0f4-64a5-00da9b95013a.png)


##### 特徴量の種類を一覧で表示 <font color="DarkGray">*sample['特徴量'].drop_duplicates()*</font>

```
sample['name'].drop_duplicates()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/dc5c3736-ca8a-b633-506b-ea28690cd9f9.png)



##### インデックス情報を表示 <font color="DarkGray">*sample.index*</font>

```
# ()を付けないように注意してください
sample.index
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/72bad93f-81a8-196b-438c-c815a234b737.png)

このデータのインデックスは1刻みで0から207まであることがわかります


##### カラム(ヘッダ)を表示 <font color="DarkGray">*sample.columns*</font>

```
# ()を付けないように注意してください
sample.columns
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/4dbecb28-dfc7-f871-0668-0e8d9d547b7a.png)

ヘッダを配列として取得することできます


##### 欠損値の有無を確認 <font color="DarkGray">*sample.isnull().sum()*</font>

```
sample.isnull().sum()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/42b6ccdf-dc72-f495-3be2-d54adc012d8b.png)

これを見るとkcal、remarks、events、paydayに欠損がありますね


##### 該当特徴量の平均値 <font color="DarkGray">*sample["特徴量"].mean()*</font>

```
# kcalの平均値を求める
sample['kcal'].mean()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/7386e501-e226-ca94-723d-037c7c699412.png)

```
# データ全ての平均値を求めることもできるが、文字データなどは残念な感じになる
sample.mean()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/80e9497b-a86a-b069-ddb6-30a8d61fd169.png)


mean()を以下の通り置き換えると、合計値などを求めることが可能

|メソッド|求めることができる値|
|---|---|
|sum()|合計値|
|min()|最小値|
|max()|最大値|
|var()|分散|
|std()|標準偏差|

これらの値は後述する基礎統計を求めた方が手っ取り早くわかります。

##### 該当特徴量における値の出現回数 <font color="DarkGray">*sample["特徴量"].value_counts()*</font>

```
sample['week'].value_counts()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/6c8acef4-8eda-9e4f-6af1-1c62c9471472.png)


##### 該当特徴量における条件を満たすデータのみ表示 <font color="DarkGray">*sample[sample["特徴量"] <条件式> ]*</font>

```
# weekが月のデータのみを表示
# 全行表示されることを防ぐためにhead()をつけています
sample[sample['week'] == '月'].head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/80cff2db-6014-fad6-c815-71518823e577.png)


```
# kcalが400以上のデータのみを表示
sample[sample['kcal'] >= 400 ].head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/9dc2317d-3bcc-57e6-9c4c-e9197e074d08.png)


##### 基礎統計量を表示 <font color="DarkGray">*sample.describe()*</font>

**数値データ**の基礎統計を表示します


```
sample.describe()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/6ed03ca0-5f6b-3b1e-a5d5-faa4f8b21acc.png)



##### ヒストグラムを表示 <font color="DarkGray">*sample["特徴量"].hist(bins=<グラフの棒の数>)*</font>

```
# figsizeに(横サイズ,縦サイズ)のタプルを渡すとグラフのサイズを指定することができます
# ここではfigsize 10:10 棒が20本のヒストグラムを表示します
sample['y'].hist(bins=20,figsize=(10,10))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/27b40d4b-a9fc-2c6a-11bc-90502eb3d062.png)


一度に全データのヒストグラムを表示することも可能です

```
sample.hist(bins=20,figsize=(10,10))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/68583db5-5104-a030-e1f2-21bb387a5506.png)



##### クロス集計する <font color="DarkGray">*pd.crosstab(sample["特徴量1"],sample["特徴量2"])*</font>

そもそもクロス集計とは、特定の二つないし三つの情報に限定して、データの分析や集計を行なう方法です

```
# 横軸にweek、縦軸にsoldoutが来るようにクロス集計を行います
pd.crosstab(sample['week'],sample['soldout'])
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/e0c6441d-c70b-fc36-1d55-10bc8f09bf33.png)

クラス集計をすることにより、各weekにおいてsoldout=0/1がどのくらいあるかを可視化することが可能です


##### 割合をクロス集計で表示 <font color="DarkGray">*pd.crosstab(sample["特徴量1"],sample["特徴量2"]).apply(lambda x: x/x.sum() * 100, axis=1)*</font>

上記のクラス集計では、該当データの数までしかもとめることができませんでした
applyを使用して割合をクロス集計で表示する方法についても記載します

```
pd.crosstab(sample['week'],sample['soldout']).apply(lambda x: x/x.sum() * 100, axis=1)
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/2729e103-d0db-3777-f89a-ce4d9e4ef271.png)


##### 相関を表示 <font color="DarkGray">*sample.corr()*</font>

```
sample.corr()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/658ac60b-3298-a936-83a7-858926d5be76.png)

表示されるのは数値データ同士の相関です
paydayは日時データなのそのままではうまく処理されません

見栄えが悪いのでpayday以外を抽出して、相関を表示します

```
sample_corr = sample[['y','soldout','kcal','temperature']]
sample_corr.corr()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/d7f98b43-6beb-c6af-9ce4-29ebf5378064.png)


正直これだけだとよくわかりません
seabornでヒートマップにするとわかりやすくなります

```
import seaborn as sns
sns.heatmap(sample_corr.corr())
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/cb991b02-2db9-1bf4-d6fb-32f3d7428bee.png)


##### 散布図グラフを表示 <font color="DarkGray">*pd.plotting.scatter_matrix(sample)*</font>

```
# figsizeを10:10で指定しています
pd.plotting.scatter_matrix(sample, figsize=(10,10))
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/c060358a-7884-e393-bd9c-208ed96d69bb.png)

右下がりの対角線上は各特徴量のヒストグラムになります


## 3.データ加工編

##### 行を削除<font color="DarkGray">*sample.drop(行番号,axis=0)*</font>

```
sample.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/56f84a60-25aa-8181-2b6f-200e5c518e19.png)

```
# 1行目を削除(インデックスは0のため、引数に0を指定)
sample2 = sample.drop(0, axis=0)
sample2.head()
```



![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/2849b7c9-00ee-48f5-1533-d6843b332cec.png)


##### 列を削除<font color="DarkGray">*sample.drop("列のヘッダー名",axis=1)*</font>

```
sample.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/56f84a60-25aa-8181-2b6f-200e5c518e19.png)

```
# kcalの列を削除
sample2 = sample.drop("kcal", axis=1)
sample2.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/86eb8e66-008c-ee9d-89c4-c8210eab654d.png)


##### 複製を作成<font color="DarkGray">*sample2 = sample.copy()*</font>

```
sample2 = sample.copy()
```

[sample2 = sampleでコピーした場合とcopy()でコピーした場合の挙動の違い](https://qiita.com/analytics-hiro/items/e8fdf8652869817851cd)


##### 該当特徴量を抽出<font color="DarkGray">*sample2 = sample[['特徴量1','特徴量2',.....]]*</font>

```
# weekとyを抽出する
sample2 = sample[['week','y']]
sample2.head()
```

引数として配列を渡すため、[]が2重になることに注意してください

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/f0a091a5-3aca-65a3-4206-ae362cbff686.png)


##### 特徴量同士を計算して新しい特徴量を作成<font color="DarkGray">*sample['新特徴量'] = sample['特徴量1'] <演算子>　sample['特徴量2']*</font>

```
# soldoutとyの値を掛け合わせたものを新しい特徴量とします
sample['soldout_x_y'] = sample['soldout'] * sample['y']
sample.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/81fa58fd-9e99-7e62-d0b8-1bc15ca29ebd.png)


##### 該当特徴量に対して関数を適用して新特徴量を作成<font color="DarkGray">*sample["特徴量"].apply( lambda x : <関数 or 式> )*</font>

```
# yを10倍したものを新しい特徴量とします
sample['10y'] = sample['y'].apply(lambda x: x * 10)
sample.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/623b4926-eddd-b77b-feac-596ae0ffc444.png)

##### 欠損値があるデータを削除<font color="DarkGray">*sample.dropna()*</font>


```
sample.isnull().sum()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/49c763fb-dcaa-1929-9578-4351cd0c0b73.png)


```
sample2 = sample.dropna()
sample2.isnull().sum()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/0dcbe42d-fff4-61cf-352f-bf83a47b4430.png)


##### 欠損値を補完<font color="DarkGray">*sample.fillna(value=<補完値>)*</font>

```
sample.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/56f84a60-25aa-8181-2b6f-200e5c518e19.png)

```
sample2 = sample.fillna(value='unknown')
sample2.head()
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/435280/5be0f480-96bf-e14d-0bc2-d2169e09fdb9.png)