Pandas入門

You can find the English version of this article here ⇒ [Pandas Fundamentals](https://qiita.com/ps_adszew/items/f7cd1caf1d373b65ac78)

# はじめに

今回の投稿の目的は、PythonライブラリであるPandasの基本的な機能と使い方を説明することです。

# 概要

Pandasは表形式のデータ（例：表計算やデータベースのデータ）を処理するためのPythonライブラリです。

データ分析や、機械学習の分野でよく使われます。

# インストール

最新版は `pip` を用いてインストールすることができます。

```
pip install pandas
```

# 概念

まずは、ライブラリで使われている概念や用語を説明しておきましょう。

**Series（シリーズ）**
 
Seriesはリストのような一次元のデータ構造であり、色々なデータ型が格納できます（`int`, `float`, `dict`等）
 
![0_series.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164173/4c4c3d36-5d3f-55d6-392b-63a7852fc882.png)


**DataFrame（データフレーム）**
 
- テーブルのように複数行と列をもつ2次元のデータ構造である 
- 各カラムをSeriesと考えることができる
- 概念的にスプレッドシートまたデータベーステーブルに類似している

![1_data_frame.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164173/a0e59367-c208-acde-4950-ca7b2ff52409.png)

今回の投稿では、DataFrameの使い方に最も注目していきます。

# DataFrame作成

多くの場合、ファイルやデータベースから既存のデータを読み込むことでDataFrameを作成します。

たとえば、CSV（カンマ区切り形式）ファイルを読み込むには、次のようにします。

```python:
import pandas as pd 
df = pd.read_csv('example.csv')
df
```

また、Pythonの`dict`オブジェクトからDataFramesを作成することもできます。

```python:
import pandas as pd 

data = {'A': [1, 2, 3],
        'B': ['X', 'Y', 'Z'],
        'C': [0.1, 0.2, 0.3]}

df = pd.DataFrame(data)

>>> df
   A  B    C
0  1  X  0.1
1  2  Y  0.2
2  3  Z  0.3
```

# カラムのデータをアクセスする

DataFrame内のデータにアクセスする方法を見てみましょう。

以下のDataFrameを例として使います。

![2_data_frame.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164173/d43b6188-79b0-dd95-1f32-78bb13fb6334.png)


1つのカラムのデータにアクセスするには、主に2つの方法があります。

![3_select_column_single.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164173/7fd5d5d0-8238-7f23-a8ee-cc1fc1c912b1.png)


複数のカラムのデータにアクセスするにはカラム名のリストを入れます。

![4_select_column_multiple.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164173/b409b475-035a-9b8b-c2f3-e12914329550.png)


# インデックス

次に、「インデックス」とは何か、どのように使えるのかを説明します。

DataFrameまたはSeriesの行と列を選択するために使用します。 

インデックスにアクセスするには、主に3つの方法があります。

- `loc`は特定のラベルを持つ列または行を取得する
- `iloc`は特定の位置で行または列を取得する
- `ix`は通常、`loc`のように動作しようとしますが、ラベルがインデックスに存在しない場合、`iloc`のように動作します。 （非推奨なので`loc`または`iloc`を使用してください）

注：インデックスで数値ラベルがよく使用されるため、行を選択したときに`iloc`と`loc`が同じ結果を返す可能性がある。 ただし、インデックスの順序が変更された場合（データがソートされた場合など）、結果は同じにならない可能性もある

それでは、`loc`が使われている使用事例を見てみましょう。

![5_loc_example_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164173/60e203cc-6ae2-f870-22f3-6cf71945ac12.png)


それでは、`iloc`を使って同じデータを選択してみましょう。

![6_iloc_example_1.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164173/7e9924d5-c49d-e152-8c39-0475ac2d5cbd.png)


多くの場合、インデックスには数値ラベルが使用されるので、行を選択する際に `iloc` と `loc` が同じ結果を返すことがあります。
 
しかし、以下の例のようにインデックスの順序が変更されている場合、結果は同じではないかもしれません。

```python:
data = {'Col1': ['A', 'B', 'C', 'D'],
        'Col2': [1, 2, 3, 4]}

df = pd.DataFrame(data)

>>> df
  Col1  Col2
0    A     1
1    B     2
2    C     3
3    D     4
```

DataFrameを`Col2`で並べ替えると、データの位置が変わるので、`loc`と`iloc`の結果が異なります。

```python:
df.sort_values('Col2', ascending=False)
  Col1  Col2
3    D     4
2    C     3
1    B     2
0    A     1
```

# 条件付きステートメント

条件付きステートメントを適用することにより、DataFrameの一部を選択できます。 これには2つの方法があります。

![7_conditional_example.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/1164173/0534d4f7-61c5-8e1f-964c-0026eed8acac.png)


*複数の条件を使用している場合は、それぞれの条件を括弧で囲む必要があることに注意してください。*

例えば、これの代わりに

```python:
df[df.Col1 == 'A' | df.Col2 == 2]

>>> TypeError: cannot compare a dtyped [int64] array with a scalar of type [bool]
```

次のようにします。

```python:
>>> df[(df.Col1 == 'A') | (df.Col2 == 2)]
  Col1  Col2
0    A     1
1    B     2
```

# 算術演算

代入を実行することで、DataFrame の内容を変更することができます。

また、以下の例にあるように、DataFrameに対して算術演算を行うこともできます。

*算術演算は変更したDataFrameのコピーを返す*

例として、Data Frame, `df`を変更しましょう

```python:
data = {'Col1': ['A', 'B', 'C', 'D'],
        'Col2': [1, 2, 3, 4],
        'Col3': [1, 2, 3, 4]}

df = pd.DataFrame(data)

>>> df
  Col1  Col2  Col3
0    A     1     1
1    B     2     2
2    C     3     3
3    D     4     4
```

まずは1つのセルの値を掛け合わせてみましょう。

```python:
>>> df.loc[0, 'Col2'] * 2
2
```

次に、`Col3`のすべての値から`1`を引いてみましょう。

```python:
df['Col3'] - 1
0    0
1    1
2    2
3    3
Name: Col3, dtype: int64
```

次に、`Col3`のすべての値に`1`を足して、その結果を元の`DataFrame`に代入してみましょう。

```python:
df['Col3'] += 1

>>> df
  Col1  Col2  Col3
0    A     1     2
1    B     2     3
2    C     3     4
3    D     4     5
```

最後に、`Col3`の値が`3`より大きい場合に`Col2`に`0`の値を代入する条件を用いてみましょう。

```python:
df.loc[df.Col3 > 3, 'Col2'] = 0

>>> df
  Col1  Col2  Col3
0    A     1     2
1    B     2     3
2    C     0     4
3    D     0     5
```
 
# よく使う関数

Pandasは算術演算に加えて、DataFrameの処理を簡単にするための多くの関数を提供されています。

いくつかよく使う関数を紹介します。

|  関数名 | 目的 | 使用事例 |
|:-----------|:------------|:------------|
| df.dropna()| 空値「NaN」のもつ行を外す|df = df.dropna()|
|df.fillna()|指定された値で空値のもつ列をデフォルトする|df = df.fillna(1)|
|df.rename()|列の名前を変更する|df.rename(columns={‘old’: ‘new’})|
|df.sort_values()|列でデータをソートする|df.sort_values(by=[’col1’])|
|df.describe()|列の統計情報を表示する (平均値, 最大値, 最小値, 等)|df.col1.describe()|

# 参考資料
https://pandas.pydata.org/Pandas_Cheat_Sheet.pdf