Pandas 基礎とよく使う機能メモ

# pandas 基本機能

基礎項目に加え、データサイエンス・機械学習、Kaggle等でよく使う機能をまとめました。

![pandas_logo.png](https://qiita-image-store.s3.amazonaws.com/0/278569/1dc707ce-2edc-ec13-fc30-c160a822d06f.png)

Pandasは、Pythonでデータ分析を行うためのライブラリで、データの読み込みや編集、統計量の表示が可能。
公式ドキュメント：http://pandas.pydata.org/pandas-docs/stable/


###0.ライブラリのインポート
```py
import pandas as pd
```

###1.シリーズとデータフレーム

*pandasには、Numpyをベースとした Series と DataFrame という型が存在する。*

#### **■ Seriesの生成**

```py
ser = pd.Series([10, 15, 20, 25])

>>> ser
0    10
1    15
2    20
3    25
dtype: int64
```

#### **■ DataFrameの生成**

```py
pd.DataFrame([[100, "a", True],
             [150, "b", False],
             [300, "c", False],
             [550, "d", True]])
```

<img width="140" alt="Screen Shot 2019-01-27 at 16.36.27.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/dd36f0f4-3fde-7c33-4cdb-eed4513cdce8.png">

　_DataFrameオブジェクトを作る方法は多数ある_

```py
pd.DataFrame(np.arange(12).reshape((3, 4)))
```

<img width="131" alt="Screen Shot 2019-01-27 at 16.37.42.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/bc8bcb76-1b2c-369c-5fa0-7b83ad0a5b4a.png">

```py
# 辞書からデータフレームを作成
pd.DataFrame({
   'A' : [1, 5, 2, 7, 3],
   'B' : [1, 6, 2, 2, 4]
})
```
<img width="77" alt="Screen Shot 2019-01-27 at 16.34.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/560c979d-67b5-920d-5392-af1670144d7e.png">

# 2.データの基本操作・整形
生成したデータを使い基本操作を解説します。

#### **■ データの作成**

```py
df = pd.DataFrame(np.arange(15).reshape((3, 5)))
df
```
<img width="165" alt="Screen Shot 2019-01-27 at 17.30.09.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/72fb1390-5b74-9164-e3ed-fb1e03b04a32.png">

#### **■ 行名、列名の指定**

```py
df.index = ["01", "02", "03"]
df.columns = ["A", "B", "C", "D", "E"]
df
```
<img width="168" alt="Screen Shot 2019-01-27 at 17.35.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/047c95d7-83f8-846f-3fe4-3064c9fe9623.png">

#### **■ 列を指定し表示**

```py
df["A"]　#A列のみ表示
```
<img width="175" alt="Screen Shot 2019-01-27 at 17.39.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/9009a9a7-2056-bc8b-717c-d283ab369004.png">

#### **■ 複数の列の指定**

```py
df[["A", "B"]] #[]忘れないように..
```
<img width="101" alt="Screen Shot 2019-01-27 at 17.41.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/2b6f976d-321a-c67f-7608-ffd1d93ce729.png">

#### **■ 行の指定**

```py
df[1:] #2行目以降を表示
```
<img width="165" alt="Screen Shot 2019-01-27 at 17.46.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/5d102249-75a7-795d-24be-5fb57b35e62c.png">

#### **■ locメソッドを使った範囲指定**

　_loc[]の引数には、行名、列名を入力する_

```py
df.loc["02", ["B", "D"]] #行"02"、列"B"と"D"の値を出力
```
<img width="183" alt="Screen Shot 2019-01-27 at 17.53.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/7f8aabd7-72f5-2630-33c1-626a66d94239.png">

#### **■ ilocメソッドを使った範囲指定**

　_loc[]の引数には、行番号、列番号を入力する_

```py
df.iloc[:2, 2:4] 
```
<img width="79" alt="Screen Shot 2019-01-27 at 18.00.03.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/170cc110-49f5-cbf3-88fa-fab37e3ed213.png">


#### **■ 条件で抽出**

```py
df[df["E"] > 5] #列Eが5より大きいデータを抽出
```
<img width="154" alt="Screen Shot 2019-01-27 at 18.35.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/c403a9ca-70a2-72a4-5b4c-edf41b049c02.png">

#### **■ queryメソッドで抽出**

*SQL構文のように複数条件で抽出可能*

```py
df.query("A > 3 and C < 10")
```

<img width="139" alt="Screen Shot 2019-01-27 at 19.33.51.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/9ab072b1-a7f8-b573-f66a-4b8c19b45be0.png">


#### **■ 列の削除**

```py
df.drop("A", axis=1) #列名を指定
```

<img width="151" alt="Screen Shot 2019-01-27 at 19.48.45.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/fa89f25d-e640-e09c-b55b-8e1a49eb0f62.png">



#### **■ 行の削除**

```py
df.drop(["01", "03"]) 
```


<img width="149" alt="Screen Shot 2019-01-27 at 21.11.28.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/6370776d-1470-85f8-3989-f8b957a93189.png">

#### **■ 列の追加**

```py
df['new']=[100,200,300]
df
```
<img width="195" alt="Screen Shot 2019-01-28 at 0.41.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/28fb3a43-320d-6ec7-d3b4-cf391596ebba.png">





# 3.データを基本情報を調べる
アヤメのデータを使って基本情報を抽出します。

#### **■ CSVファイルの読み込み**

```py
df = pd.read_csv("/Users/..../iris.csv") 

#CSVファイルのローカルアドレスをタプルに入力
#CSVに区切りがある場合はタプルに("~.scv", sep = ",")のように指定する
```

#### **■ 最初の5行のみ表示**

```py
df.head() #タプル内に数字を指定し任意の行数に変えることも可能
```
<img width="440" alt="Screen Shot 2019-01-27 at 21.13.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/e01bc3df-bfd1-56f7-9e63-d6a015beb579.png">


#### **■ 最後の5行のみを表示**

```py
df.tail()
```

<img width="473" alt="Screen Shot 2019-01-27 at 21.13.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/6971a146-eb91-93c1-a9ff-4f139da9f685.png">


#### **■ データフレームの大きさを確認**

```py
>>> df.shape

(150, 5) 　#150行5列のデータフレーム
```

#### **■ 基本統計量をまとめて表示**

```py
df.describe()
```
<img width="385" alt="Screen Shot 2019-01-27 at 22.03.00.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/02ddda08-8177-29f5-6c9c-fbf7f53765dd.png">

#### **■ 基本統計量メソッド**
 - **.max()** 　最大値
 - **.min()**　最小値
 - **.mode()** 　最頻値
 - **.mean()** 　平均値
 - **.median()** 　中央値
 - **.std()** 　標準偏差
 - **.count()** 　件数
 - **.corr()**　相関係数（列間のデータの相関関係を数値化、主にテーブル全体に対して使う。）
 - **.unique()**　カテゴリカルデータの項目を表示
 - **.value_counts()** 　項目別数量

```py
df.mean() #列ごとの平均を出力
```
<img width="195" alt="Screen Shot 2019-01-29 at 1.56.19.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/07eccb69-971e-6d25-804a-fe877821187b.png">

# 4.その他の実用的な整形メソッド
データ分析で使う様々なメソッドを紹介します。
3.同様アヤメのデータ(df)を使用します。

#### **■ ソート・並べ替え**

```py
df.sort_values(by="PetalWidth")
#"PetalWidth"列でソート
#デフォルトでは昇順
```
<img width="465" alt="Screen Shot 2019-01-28 at 11.37.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/54cd5f50-c4f3-46c5-9ec6-4d957d4d0b2f.png">

```py
df.sort_values(by="PetalWidth",ascending=False)
#降順
```
<img width="453" alt="Screen Shot 2019-01-28 at 11.38.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/74e05513-7bb8-0870-388a-51143be5b172.png">


#### **■ グループバイ**


```py

df_groupby = df.groupby("Name") #Name列で集約されたオブジェクトを作成
```
```py
df_groupby.mean() #Nameのカテゴリー別平均
```
<img width="440" alt="Screen Shot 2019-01-28 at 13.47.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/43496239-e5d8-b653-027b-147614eac4c6.png">

```py
df_groupby.describe() #カテゴリー別基本統計量をまとめて表示
```
<img width="1032" alt="Screen Shot 2019-01-28 at 13.50.21.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/d01f348d-8ca0-f627-55b6-ae0086322347.png">


#### **■ ピポッドテーブル**

 *新しくデータフレームを作成します*

```py
df=DataFrame([['1-09','A','Apple',150],
              ['1-10','A','Banana',100],
              ['1-10','C','Orange',200],
              ['1-10','C','Aplle',170],
              ['1-11','B','Orange',200],
              ['1-11','D','Orange',210],
              ['1-12','B','Banana',110]],
              columns=['Date','Shop','Fruit','Price'])
df
```
<img width="205" alt="Screen Shot 2019-01-28 at 21.27.57.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/cd237f61-3381-e3c2-ed83-f448791efe88.png">

```py
df.pivot_table(values = 'Price', index = 'Shop', aggfunc = sum)
#店舗別の売上合計
```
<img width="92" alt="Screen Shot 2019-01-28 at 21.32.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/fbd12038-4f3a-d34c-7144-f5f5b266d93a.png">

```py
df.pivot_table(values = 'Price', index = 'Shop', columns = 'Fruit', aggfunc = sum)
#columnsを追加し商品別に売上を表示
```
<img width="248" alt="Screen Shot 2019-01-28 at 22.07.41.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/2f165d4e-68cb-9061-e7e2-892cbabbf8ec.png">

```py
df.pivot_table(values = 'Price', index = 'Shop', columns = 'Fruit', 
               aggfunc = sum, fill_value = 0)
#fill_value = 0 でNaNを0に変換
```
<img width="253" alt="Screen Shot 2019-01-28 at 22.14.15.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/0c99750f-d5da-797b-ccd2-93995f0bd2c3.png">

```py
df.pivot_table(values = 'Price', index = 'Shop', columns = 'Fruit', 
               aggfunc = sum, fill_value = 0, margins = True)
#margins = True 合計を表示
```
<img width="287" alt="Screen Shot 2019-01-28 at 22.18.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/58672a7f-270f-1df5-f252-9ea75364e331.png">

```py
df.pivot_table(values = 'Price', index = ['Date','Shop'], columns = 'Fruit', 
               aggfunc = sum, fill_value = 0, margins = True)
#'Date'を加えてindexを階層化
```
<img width="331" alt="Screen Shot 2019-01-28 at 22.22.47.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/e39d2476-6431-aff1-013a-386bf73cb4e5.png">




#### **■ データフレームの連結**

*データフレーム df を改めて確認*

```py
df
```
<img width="207" alt="Screen Shot 2019-01-28 at 22.36.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/fd948910-ff05-8fc9-9106-364eccb821f9.png">

*同じ構造をもつ df_2 を作成*

```py
df_2 = DataFrame([['1-13','D','Banana',100],
                 ['1-13','C','Orange',200],
                 ['1-13','B','Apple',150],
                 ['1-14','C','Aplle',170],
                 ['1-14','A','Banana',120],
                 ['1-15','C','Orange',210],
                 ['1-15','D','Banana',100]],
                 columns=['Date','Shop','Fruit','Price'])
df_2
```
<img width="205" alt="Screen Shot 2019-01-28 at 22.48.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/a13a4144-2200-7a3c-0520-c5148b2ae5f0.png">


*df、 df_2 を行で連結*

```py
pd.concat([df, df_2], ignore_index=True)
#ignore_index=True でインデックスの振り直しが可能
```
<img width="213" alt="Screen Shot 2019-01-28 at 22.48.55.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/e413ac44-b6f8-0a05-e167-60dead13dd35.png">

*df、 df_2 を列で連結*

```py
pd.concat([df, df_2], axis=1, join_axes=[df.index])
```
<img width="393" alt="Screen Shot 2019-01-28 at 23.01.06.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/1feac42b-d6ce-3ee9-634f-2e9a32cfe97a.png">

*連結元のデータをラベルで分けて連結*

```py
pd.concat([df, df_2], axis=1, join_axes=[df.index], keys=['X', 'Y'])
```
<img width="390" alt="Screen Shot 2019-01-28 at 23.17.58.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/9429f73f-aac6-c9e9-888b-86f926a8f35d.png">

#### **■ データフレームの結合**

*引き続きデータフレーム df を使用*

```py
df
```
<img width="207" alt="Screen Shot 2019-01-28 at 22.36.14.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/fd948910-ff05-8fc9-9106-364eccb821f9.png">

*df_3を作成 *

```py
df_3 = DataFrame([['1','A','East'],
                 ['2','B','West'],
                 ['3','C','South'],
                 ['4','D','North'],
                 ['5','E','EC']],
                 columns=['Shop_No','Shop','Area'])
df_3
```
<img width="184" alt="Screen Shot 2019-01-29 at 1.20.04.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/affd0e02-0469-0656-1131-7accce1f6bb7.png">

*'Shop'を基点に結合*

```py
pd.merge(df, df_3, on='Shop')
```
<img width="324" alt="Screen Shot 2019-01-29 at 0.58.49.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/7be1a8f1-3966-1efc-34cd-1542d6c90e37.png">

*howで結合方法を選択可能*

- inner: 両方のデータに含まれるキーだけを残す。(内部結合)
- left: 1つめのデータのキーをすべて残す。(左外部結合)
- right: 2つめのデータのキーをすべて残す。(右外部結合)
- outer: すべてのキーを残す。（完全外部結合）

```py
pd.merge(df, df_3, on='Shop', how='left')
```
<img width="319" alt="Screen Shot 2019-01-29 at 1.23.29.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/1228d897-f8bf-3db1-0f98-85610695da3d.png">


```py
pd.merge(df, df_3, on='Shop', how='right')
```
<img width="317" alt="Screen Shot 2019-01-29 at 1.23.34.png" src="https://qiita-image-store.s3.amazonaws.com/0/278569/cd68ff00-0d02-cbdf-ae8f-068f3c74c756.png">



# 5.その他メモ

#### **■ インデックス番号で抽出**

```py
df.ix[5:10]
```

#### **■ データ変換（DataFrame → Numpy配列）**

*アルゴリズムによってはDataFrameのままでは読み込めないものもあり、その際に変換が必要。*

```py
df["A"].values  #列AをNumpy配列に変換
```

#### **■ データフレームに関数を適用**

```py
#データフレームの全ての値を2乗にしたい場合
func = lambda x: x**2
df.apply(func)

#列に適用し更新したい場合
df["A"] = df["A"].apply(func)


#タプルにそのまま関数を書いても良い
df.apply(lambda x: x**2)
```

#### **■ インデックス変更・更新** 

```py
df.set_index('Date', inplace=True)
#第一引数にindexにしたい列名を入力
#inplace=True でデータを更新
```
#### **■ オブジェクト型のみに絞る / オブジェクト型を除外**

```py
#オブジェクト型のみ出力
df.select_dtypes(include=['object'])

#オブジェクト型を除外
df.select_dtypes(exclude=['object'])
```


#### **■ エクセルファイルの読み込み**

```py
pd.read_excel("~.xlsx")
```