備忘録：pandas テーブルデータ整形

# はじめに
社内・社外でデータサイエンス、統計の教育を務める機会が増えてきたため
pandas初心者向けに備忘録として、記事を書かせていただきます
テーブルデータ整形時、あるあるの処理を備忘録としてちょっとまとめておきます

# データのインポート
~~~py
import pandas as pd
data = pd.read_csv("https://raw.githubusercontent.com/mwaskom/seaborn-data/master/iris.csv")
~~~


# データの確認

##### データの確認
~~~py
data.head(5)
~~~
※カッコ内の数字が表示する行数
↓実行すると

:::note info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/6a0e9464-0eea-ff92-b94f-e50df36ad0e3.png)
:::
---

##### データサイズの確認
~~~py
data.shape
~~~
↓実行すると、行数・列数を確認できる

:::note info
(150, 5)
:::

---

##### ざっくり統計量の確認
~~~py
data.describe()
~~~
↓実行すると

:::note info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/fbff5a4e-275e-14a5-e1dc-6f2eaa4c4b16.png)
:::

##### 欠損値の確認
~~~py
data.isna().any()
~~~

:::note info
Falseであれば、欠損値がないことを確認できる
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/2c96d6f1-39ae-2cfa-464f-b1cebddc5e33.png)

:::

# データの整形
##### 使用する因子を絞る
sepal_lengthとspeciesの因子を抽出しcut_dataに代入する

~~~python
use_col=['sepal_length','species']
cut_data=data[use_col]
cut_data.head()
~~~
↓実行すると

:::note info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/205b0cd1-c4ac-adbf-edda-ae3377582520.png)
※sepal_lengthとspeciesのみを抽出できる
:::
---

##### 新たな因子を追加する
categoryをすべて1として追加する場合
~~~py
cut_data['category']=1
cut_data.head()
~~~
↓実行すると

:::note info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/5af43b74-b815-0e97-3b59-f5bf6185afff.png)
:::

さらにsepal_lengthの個々の値とsepal_lengthの平均値の差をresidualという名前の因子で追加する場合

~~~py
cut_data['residual']=cut_data['sepal_length']-cut_data['sepal_length'].mean()
cut_data.head()
~~~
↓実行すると

:::note info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/3e57e358-b993-cdaa-a32c-23222b7d4864.png)
:::
---


# データの正規化
sepal_lengthに対して、min-max Normalizationを実施するとき

```math
\frac{X-X_{min}}{X_{max}-X_{min}}
```

~~~py
len_nol=( cut_data['sepal_length'] - cut_data['sepal_length'].min() )/( cut_data['sepal_length'].max() - cut_data['sepal_length'].min() )
cut_data['len_nol']=len_nol
cut_data.describe()
~~~
↓実行するとlen_nolの最小値が0,最大値が1となっていることを確認できる

:::note info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/25460277-66b0-e879-8567-c7e1268df436.png)
:::


# データの標準化
sepal_lengthに対して標準化(standardization)を実施すると
```math
\frac{X-μ}{σ}
```

~~~py
len_sta = ( cut_data['sepal_length'] - cut_data['sepal_length'].mean() ) / cut_data['sepal_length'].std()
cut_data['len_sta']=len_sta
cut_data.describe()
~~~
↓実行するとlen_staの平均が0,分散が1となっていることを確認できる

:::note info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/9053f4e7-21ca-721a-c9d1-6736860432f3.png)
:::

# データの結合
列方向にデータを結合する場合
dataの列の最後にcut_dataのpetal_lengthの正規化とpetal_lengthの標準化したものを結合する場合、

~~~py
new_data=pd.concat([ data, cut_data['len_nol'], cut_data['len_sta'] ],axis=1)
new_data.head()
~~~

↓実行すると

:::note info
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2696103/5ba5ffae-ed0f-3050-f476-baacec1bb29d.png)
:::

# データの保存
csv形式で保存する

~~~py
new_data.to_csv("./newdata.csv")
%ls
~~~
実行するとカレントディレクトリにてnewdata.csvが保存されていることが確認できる

# 最後に
これらがサラッと書ければ概ね問題ないかなと感じます
必要なものはまた追記していこうと思います