Pythonデータ分析手順のカンニングシート（仮）

おつかれさまです。
必要に迫られており、クソ焦って勉強した。

とりあえずWEB上でカンニングできるように、1番素人がしっくりきそうなデータ分析手順のカンニングシートをQiitaにアップ。



## 必要なライブラリのインストール

```
# pandasはデータの取扱系ライブラリ
import pandas as pd
# とくにDataFrameはよく使うので、個別importしておく
from pandas import DataFrame
# numpyは行列計算系ライブラリ
import numpy as np
# matplotlibとseabornはグラフ系ライブラリ
import matplotlib.pyplot as plt
import seaborn as sns
# Jupyter Notebookを使う想定なのでブラウザ上にグラフ表示できるように設定
%matplotlib inline
```

## データの取り込み

CSVファイルで取り込む場合は、
実行しているipynbファイルと同じディレクトリにCSVファイルおいた状態で、

```py
df = pd.read_csv('CSVファイル名', header = None)
# `header=None`を指定せず`pd.read_csv('CSVファイル名')`とした場合は1行目が自動的にカラム名として挿入される
```

Excelファイルで取り込む場合は、
実行しているipynbファイルと同じディレクトリにExcelファイルおいた状態で、

```py
df = pd.read_excel('Excelファイル名', sheetname='シート名', header = None)
# `header=None`を指定せず`pd.read_excel('Excelファイル名', sheetname='シート名')`とした場合は1行目が自動的にカラム名として挿入される
```

コピペで取り込む場合は、
コピーした状態で、

```py
df = pd.read_clipboard(header = None)
# `header=None`を指定せず`pd.read_clipboard()`とした場合は1行目が自動的にカラム名として挿入される
```

とりあえず、今回のサンプルデータは、
https://www.kaggle.com/c/titanic/data
の`training.csv`と仮定してすすめてきまーす。
Kaggleで有名なタイタニックでどんな人が生還したかのデータです！

## データを眺める

実際のデータを見たいときは、

```py
df.head()
# ()の中が何もなければ最初の5行、数字いれればその行数分を上から見れる
```

[![Image from Gyazo](https://i.gyazo.com/bd8e82277fc8c6afcd40711305a80540.png)](https://gyazo.com/bd8e82277fc8c6afcd40711305a80540)

各列のデータ数や平均、標準偏差、最小値、中央値、最高値とかを見たいときは、

```py
df.describe()
```

単純にデータの行列のサイズを見たいときは、

```py
df.shape
```

## カラム名を変える

カラム名が気に入らないときは、

```py
df = df.rename(columns = {'変更前カラム名1': '変更後カラム名1', '変更前カラム名2': '変更後カラム名2'})
```

## 欠損データがどれくらいあるか調べる

```py
df.info()
```

## 欠損データをなんとかする

欠損データを消す場合は、

```py
df = df.dropna()
# 1つでもNaNが含まれる行が削除される
```

あるカラムに欠損データがあって、その行を消す場合は、

```py
df = df.dropna(subset=['カラム名'])
# 指定したカラム名にNaNが含まれる行が削除される
```

欠損データに列ごとに平均値、中央値、最頻値を入れたいときは、

```py
# 平均値を入れたいときは
df = df.fillna(df.mean())
# 中央値を入れたいときは
df = df.fillna(df.median())
# 最頻値を入れたいときは
df = df.fillna(df.mode().iloc[0])
```

欠損データに前後の値から推測してデータを入れたいときは、

```py
# 列方向に推測したデータを入れたいときは
df = df.interpolate()
# 行方向に推測したデータを入れたいときは
df = df.interpolate(axis=1)
```

欠損データに同列の前後の値を入れたいときは、

```py
# 前の値を入れたいときは
df = df.fillna(method='ffill')
# 後の値を入れたいときは
df = df.fillna(method='bfill')
```

欠損データに特定のデータを入れる場合は、

```py
df = df.fillna(入れたい値)
```

列によって欠損データに入れたい値が異なるときは、

```py
df = df.fillna({'カラム名1':入れたい値,'カラム名2':入れたい値,'カラム名3':入れたい値})
```

## 新しい列を追加する

たとえば、`Sex`カラムの「male」「female」のデータをもとに、「0」「1」データの`Male`カラムを作りたいときは

```py
df['Male'] = df['Sex'].map({'male':1,'female':0})
```

たとえば、`Age`カラムをもとに、「adult」「child」「baby」のデータを持つ`Age_range`カラムを作りたいときは

```py
def adult_child_baby(age):
    if age < 4:
        return 'baby'
    elif age < 19:
        return 'child'
    else:
        return 'adult'

df['Age_range'] = df['Age'].apply(adult_child_baby)
```

たとえば、`Sex`カラムと`Age_range`カラムをもとに、「0」「1」データの`Boy`カラムを作りたいときは

```py
def check_boy(human):
    sex, age_range = human
    if sex = 'male' and age_range = 'child':
        return 1
    else:
        return 0

df['Boy'] = df[['Sex','Age_range']].apply(check_boy,axis=1)
```

最終的に下記のような感じになります！

[![Image from Gyazo](https://i.gyazo.com/4bd52dd9655120c6822d7e3567eef781.png)](https://gyazo.com/4bd52dd9655120c6822d7e3567eef781)

## ピボット化

Excelでいうピボットテーブルみたいなもの。
たとえば、行が`Age_range`で列が`Pclass`で値を`Age`の平均値にしたいときは、

```py
pd.pivot_table(df, values='Age',index='Age_range', columns='Pclass', aggfunc='mean')
# valueに値、indexに行項目、columnsに列項目、aggfuncに値の計算方法を指定
```

で下記みたいな感じになります！

[![Image from Gyazo](https://i.gyazo.com/5498f7234eb53db8c7312fd976fb1a1c.png)](https://gyazo.com/5498f7234eb53db8c7312fd976fb1a1c)

たとえば、行が`Age_range`で列が`Survived`で値を`Age`のデータ数にしたいときは、

```py
df.pivot_table(values='Age',index='Age_range',columns='Survived',aggfunc="count")
```

で下記みたいな感じになります！

[![Image from Gyazo](https://i.gyazo.com/a4268ff3519b0388335509afb51859e2.png)](https://gyazo.com/a4268ff3519b0388335509afb51859e2)

## グループ化

そのまんま、グルーピングです。
たとえば、`Age_range`ごとに平均値を出したいときは、

```py
df.groupby(['Age_range']).mean()
```

で下記みたいになります！

[![Image from Gyazo](https://i.gyazo.com/8560e49ad1533916a615032d2f347eac.png)](https://gyazo.com/8560e49ad1533916a615032d2f347eac)

グルービングは二重にできたりもします。
例えば下記みたいな感じ。

```py
df.groupby(['Survived','Age_range']).mean()
```

すると下記みたいになります。

[![Image from Gyazo](https://i.gyazo.com/d86ac8f8a2de1d80e596f723f86f0896.png)](https://gyazo.com/d86ac8f8a2de1d80e596f723f86f0896)

## カウント

これも結構つかえます。
例えば`Age_range`のそれぞれのデータ数がほしいときは、

```py
df['Age_range'].value_counts()
```

でこんな感じに表示されます！

[![Image from Gyazo](https://i.gyazo.com/7d46eee06816ff8c50271c9a68da1d16.png)](https://gyazo.com/7d46eee06816ff8c50271c9a68da1d16)


## 棒グラフ化

まずはヒストグラムってやつから。

```py
df['Age'].hist(bins=50)
# binsで棒の本数を指定
```

[![Image from Gyazo](https://i.gyazo.com/687f70a9731287f58eead84ffba4a2ae.png)](https://gyazo.com/687f70a9731287f58eead84ffba4a2ae)

つぎに棒グラフ。

```py
# まずSurvivedごとにAgeの標準偏差をしらべておく
std = df.groupby('Survived')['Age'].std()
# SurvivedごとのAgeの平均値を棒グラフ（bar）にして標準偏差の棒をつける
df.groupby('Survived')['Age'].mean().plot(yerr=std, kind='bar', legend=False)
# kind='bar'で棒グラフになる
# legendはTrue, Falseで凡例はつけるかどうか
# yerrでエラーバーをいれれる
```

[![Image from Gyazo](https://i.gyazo.com/196b72e823882fa45a92684859abc42b.png)](https://gyazo.com/196b72e823882fa45a92684859abc42b)

つぎは横棒グラフ。

```py
df.groupby('Sex')['Age'].mean().plot(kind='barh', legend=False, figsize=(5,3))
# kind='barh'で横棒になる
# figsizeでグラフの大きさ
```

[![Image from Gyazo](https://i.gyazo.com/cfd3923f674043ddd0c733dc9e124559.png)](https://gyazo.com/cfd3923f674043ddd0c733dc9e124559)

次は、データ数の棒グラフ化。

```py
sns.countplot('Age_range',data=df)
# 引数にカテゴリーを指定
```

[![Image from Gyazo](https://i.gyazo.com/671d3e2d807532aa18eba8e4bb1a326a.png)](https://gyazo.com/671d3e2d807532aa18eba8e4bb1a326a)

データ数の棒グラフ化は更に細分化できる。

```py
sns.countplot('Age_range',data=df,hue='Survived', order=['adult','child','baby'])
# hueで細分化したいカテゴリを指定
# orderで棒グラフの順番を指定できる
```

[![Image from Gyazo](https://i.gyazo.com/e16edd50efd76bdc0eebbaab0f579bb7.png)](https://gyazo.com/e16edd50efd76bdc0eebbaab0f579bb7)

Seaborn(barplot)を使うと、これらのカテゴリ分解やエラーバーが一瞬でできる！

```py
sns.barplot(x='Age_range', y='Survived', hue='Sex', data = df)
# エラーバーは信頼区間95%を表現
```

[![Image from Gyazo](https://i.gyazo.com/5251d5b7bb669a5afb8083ef4f8afef0.png)](https://gyazo.com/5251d5b7bb669a5afb8083ef4f8afef0)

Seaborn(distplot)を使うと、ヒストグラムにそれっぽい曲線が追加される！

```py
sns.distplot(df['Age'].dropna(), bins=50, color='gray')
# 曲線はカーネル密度推定
# distplotは欠損データがあるとエラーになるのでdropna()を忘れないこと
# colorで色が指定できたりもする
```

[![Image from Gyazo](https://i.gyazo.com/2f1426b9f39c3147135a4b1233bdd211.png)](https://gyazo.com/2f1426b9f39c3147135a4b1233bdd211)

## なんかそれっぽいグラフ化

何という名前かわからんが、Seaborn(factorplot)を使うと下記みたいになる。

```py
sns.factorplot('Age_range','Survived',hue='Pclass',data=df, order=['adult','child'])
```

[![Image from Gyazo](https://i.gyazo.com/5be6da2e0a8dad1303993afacd23d642.png)](https://gyazo.com/5be6da2e0a8dad1303993afacd23d642)

さらに何という名前かわからんが、Seaborn(lmplot)を使うと下記みたいになる。

```py
sns.lmplot('Age','Survived', hue='Sex', data=df, hue_order=['female', 'male'], aspect=3)
# 直線は回帰直線
# 影は信頼区間95%を表現
# aspectでグラフの縦横比率を指定できる
```

[![Image from Gyazo](https://i.gyazo.com/c4aa768cfbbc787083dad72bbeef8978.png)](https://gyazo.com/c4aa768cfbbc787083dad72bbeef8978)

## 散布クラフ化

タイタニックデータは数値データが少ないので、数値データの多い別のものを準備！

```py
df2 = sns.load_dataset('car_crashes')
df2.head()
```

こんな感じです。
これは縁起悪いですが、クルマの事故データです。

[![Image from Gyazo](https://i.gyazo.com/d0cff3bffa93cd6934d64014a1eb60b2.png)](https://gyazo.com/d0cff3bffa93cd6934d64014a1eb60b2)

pyplotのscatterメソッドをつかったら散布グラフになります！

```py
plt.scatter(df2['speeding'], df2['alcohol'])
# 第一引数にX軸にしたいもの、第二引数にY軸にしたいものを指定
```

[![Image from Gyazo](https://i.gyazo.com/156ba6e9f8fe53d60c08f5d2662d6b19.png)](https://gyazo.com/156ba6e9f8fe53d60c08f5d2662d6b19)

pyplotはいろんなことを指定できます。

```py
plt.scatter(df2['speeding'], df2['alcohol'])
# X軸とY軸の最大値と最小値を指定
plt.xlim([0, 10])
plt.ylim([0, 12])
# X軸とY軸の名前を指定
plt.xlabel('speeding')
plt.ylabel('alcohol')
```

[![Image from Gyazo](https://i.gyazo.com/e6532f7beefdaea4a841ae0b3652c4c8.png)](https://gyazo.com/e6532f7beefdaea4a841ae0b3652c4c8)

でも！Seaborn(scatterplot)を使うと一瞬で散布グラフができます！

```py
sns.scatterplot(x='speeding', y='alcohol', data=df2)
```

[![Image from Gyazo](https://i.gyazo.com/ca6af7a1b34150fbff615e90c045c123.png)](https://gyazo.com/ca6af7a1b34150fbff615e90c045c123)

さらにSeaborn(jointplot)を使うと散布グラフとヒストグラムの合体版になります！

```py
sns.jointplot('speeding', 'alcohol', df2)
```

[![Image from Gyazo](https://i.gyazo.com/f4fe9e9bf9fff2cb1511a203519cdead.png)](https://gyazo.com/f4fe9e9bf9fff2cb1511a203519cdead)

さらにさらに！なんかスゲーことになります。

```py
sns.jointplot('speeding', 'alcohol', df2, kind="reg")
# kind="reg"を指定すると回帰直線と信頼区間95%の影がでてくる
```

[![Image from Gyazo](https://i.gyazo.com/64a7cd18b3e7262350c5c439ba09539f.png)](https://gyazo.com/64a7cd18b3e7262350c5c439ba09539f)

Seaborn(pairplot)を使うと、全通りの散布グラフ！！

```py
sns.pairplot(df2)
# pairplotの引数は欠損値があるとエラーになる
```

[![Image from Gyazo](https://i.gyazo.com/a58d86bd630c10f63aac72c681a47c5b.png)](https://gyazo.com/a58d86bd630c10f63aac72c681a47c5b)

Seaborn(pairplot)でカテゴリ細分化までできる。

```py
sns.pairplot(df2, hue='abbrev')
```

[![Image from Gyazo](https://i.gyazo.com/a9ac5b2c67b3ca04c884c327f6902b1a.png)](https://gyazo.com/a9ac5b2c67b3ca04c884c327f6902b1a)

## ヒートマップ

もはや説明不要だろう。
Seabornはかってにスゴいグラフになる。

```py
sns.heatmap(df2.corr(), annot=True)
# annot=Trueで各マスに数値が入る
```

[![Image from Gyazo](https://i.gyazo.com/007e0d106d9a8d6956ffa3497ba9ab53.png)](https://gyazo.com/007e0d106d9a8d6956ffa3497ba9ab53)

clustermapを使うと樹形図てきなものまで入る。

```py
sns.clustermap(df2.corr(), annot=True)
```

[![Image from Gyazo](https://i.gyazo.com/eae6d7af80d6b74f951678b8174f7d42.png)](https://gyazo.com/eae6d7af80d6b74f951678b8174f7d42)

## 折れ線グラフ

折れ線グラフは時系列データを対象にするとわかりやすいので、Googleの株価を取得してみる。

```py
import pandas_datareader.data as pdr
import datetime
end = datetime.date.today()
start = end - datetime.timedelta(days=10)
df3 = pdr.DataReader('GOOG', 'yahoo', start, end)
df3.head()
```

こんな感じ。

[![Image from Gyazo](https://i.gyazo.com/60bd4ac5feb42cfd95cea46f02a9f63b.png)](https://gyazo.com/60bd4ac5feb42cfd95cea46f02a9f63b)

対象データに対してplotメソッドを使うと下記のような感じになる。

```py
df3['High'].plot(legend=True, figsize=(10,4))
```

[![Image from Gyazo](https://i.gyazo.com/2c37b2460997c0c9cb9adf42111ce65c.png)](https://gyazo.com/2c37b2460997c0c9cb9adf42111ce65c)

点や、点と点をむずぶ線のスタイルを変更することもできる。

```py
df3[['High', 'Low']].plot(figsize=(10,4), legend=True, linestyle='--', marker='o')
# markerで点スタイルを指定
# linestyleで点と点を結ぶ線スタイルを指定
```

[![Image from Gyazo](https://i.gyazo.com/46917bcd5b5f5a48a496d9fd7c94b6da.png)](https://gyazo.com/46917bcd5b5f5a48a496d9fd7c94b6da)

ここでやはりSeabornを使えば一瞬。

```py
sns.lineplot(x=df3.index, y='High', data=df3)
```

[![Image from Gyazo](https://i.gyazo.com/b0491a12b91b37f16eeafc2a99685471.png)](https://gyazo.com/b0491a12b91b37f16eeafc2a99685471)

## ストーリー仕立てでイメージを深めるなら
ストーリー仕立てでイメージを深めるなら、こちらの教材が良い。有料なので、まずは無料部分を読んでニーズとマッチするか判断しましょう。
https://www.techpit.jp/courses/30/curriculums/31/sections/264/parts/906

## 参考にさせていただきました！

- [【世界で5万人が受講】実践 Python データサイエンス](https://www.udemy.com/course/python-jp/)
- [マンガでわかる統計学](https://www.amazon.co.jp/gp/product/4274065707/)
- [マンガでわかる統計学 回帰分析編](https://www.amazon.co.jp/gp/product/4274066142)
- [Google流資料作成術](https://www.amazon.co.jp/gp/product/4534054726)
- [pandasで欠損値NaNを除外（削除）・置換（穴埋め）・抽出](https://note.nkmk.me/python-pandas-nan-dropna-fillna/)
- [pandasで欠損値NaNを前後の値から補間するinterpolate](https://note.nkmk.me/python-pandas-interpolate/)
- [機械学習入門！seabornで便利でかっこいいグラフを簡単にplot！](https://www.sejuku.net/blog/61017)
- [pythonでデータを可視化したいならseabornを使おう！](https://qiita.com/HiromuMasuda0228/items/babdfa175815fb3e3a94)