実務で使うpandas/DataFrame Tips


# はじめに
機械学習をはじめとしたデータ分析では、データ前処理は必須であり、pandasをかなり使う。特に、テーブルデータを扱うDataFrameの使用頻度は極めて高い。
と言いつつ、いつも忘れてしまうので、ここでまとめます。

githubに実際のコードを挙げているので、参考にしてください。
https://github.com/andever-flatfish/pandas-tips/blob/master/notebook/pandas-tips.ipynb


まずは、以下のDataFrameを使って、各Tipsをする。

```python
import pandas as pd

df = pd.DataFrame([['tokyo', 'male', 21, 165, 63],
                   ['osaka', 'male', 28, 170, 71],
                   ['fukuoka', 'female', 32, 175, 58],
                   ['tokyo', 'male', 21, 165, 63],
                   ['osaka', 'female', 28, 175, 70],
                   ['fukuoka', 'male', 32, 155, 58],
                   ['tokyo', 'female', 21, 165, 63],
                   ['osaka', 'male', 28, 172, 67],
                   ['fukuoka', 'male', 42, 155, 48]],
                   columns=['area', 'gender', 'age', 'height', 'weight'])
```


<img width="266" alt="sample_df.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/cd0648cb-5aea-2e89-63c1-f85a446ec5d5.png">



#データの型の確認・型の変換

pythonは動的型付け言語なので、基本的に型を意識する必要はありません。ただ、想定外のことでエラーになることもよくあります。
例えば、int型だと思っていたデータが、1つのデータだけスペースが入っていて、object型になっているとかです。
そのような際には、以下でデータの型を確認しましょう。

```python

df.dtypes
```

```
area      object
gender    object
age        int64
height     int64
weight     int64
dtype: object
```

1つのカラムのみ確認したい場合は、以下で確認できます。

```python

df['height'].dtype
```

```
dtype('int64')
```

int型をfloat型に変換したい場合は、以下のようにすれば出来ます。
上記のdf['height'].dtypeで確認すると、変換されていることが分かります。

```python

df['height'] = df['height'].astype(float)
```
ただし、object型をint型やfloat型に変換するには、object型になったデータ（例えばスペースとか）を修正か除去した上で、astypeで変換する必要があります。


#DataFrameのカラム名の確認
DataFrameのカラム名を確認したいことはよくあります。さらに、カラムごとに何かの処理をしたい場合は、カラム名をリストで保持しておくと便利です。

```python

df_columns = list(df.columns)
print(df_columns)
```

```
['area', 'gender', 'age', 'height', 'weight']
```

#特定の行のデータのみ抽出する

ある特定の条件に当てはまるデータのみを行ごと抽出することができる。
例えば、dfの中で'area'が'fukuoka'のみのデータを抽出したい場合は、以下のように抽出できる。

```python

part_of_df1 = df[df['area']=='fukuoka']
```

<img width="268" alt="part_of_df.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/6ad722b2-07df-360d-9512-a90d4d59167a.png">


また、dfの中で'area'が'tokyo'もしくは'osaka'のデータを抽出したい場合は、以下のように抽出できる。

```python

part_of_df2 = df[df['area'].isin(['tokyo', 'osaka'])]
```

<img width="255" alt="part_of_df2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/3da5b5f3-3402-ba45-dc3d-6dfd8cb1daf3.png">


nullのデータだけ抜き出したい場合は、以下のように書く。

```python

part_of_df3 = df[df['area'].isnull()]
```


実業務ではnullのデータだけ抜き出したい場合よりも、nullでないデータを抜き出す場合の方が多いように思う。
nullでないデータを抜き出す場合は、以下のように書く。

```python

part_of_df4 = df[~df['area'].isnull()]
```



#インデックスの数字を振り直す

特定の行のデータのみ抽出すると、indexが元のDataFrameのindexのままなので、以下のようにindexを振り直す。

```python

part_of_df1.reset_index(drop=True, inplace=True)
```

<img width="268" alt="reset_index_part_of_df.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/20a03842-2b34-534d-7288-576b70935115.png">


#カラムの並び順の変更

DataFrameのカラムを並び順を変更したい場合は、並び替えたい順のカラムをリストにして、そのリストを呼べば良い。

```python

sorted_columns_list1 = ['height', 'weight', 'gender', 'area', 'age']
sorted_df1 = df[sorted_columns_list1]
```

<img width="266" alt="sorted_df1.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/8f11c93d-bd50-30b1-4173-05886ad4d68e.png">

並び替えだけでなく、特定のカラムのみを抽出することもできる。

```python

sorted_columns_list2 = ['area', 'gender', 'age']
sorted_df2 = df[sorted_columns_list2]
```

<img width="169" alt="sorted_df2.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/84968a1f-03d7-b73f-d0a0-62fc3a5ff3ea.png">

#カラム名の変更
renameを使って、以下のようにカラム名を修正する。

```python

rename_df = df.rename(columns={'area':'エリア',
                               'gender':'性別', 
                               'age':'年齢', 
                               'height':'身長', 
                               'weight':'体重'})
```

<img width="237" alt="rename_df.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/2386e8b6-eae1-ec5a-1af3-55286ffa7891.png">


#他のデータフレームをUnionする

同じカラム名の違うデータをunionする際には、appendを使う。

```python

other_df = pd.DataFrame([['hokkaido', 'male', 25, 162, 60],
                         ['hokkaido', 'female', 38, 179, 81]],
                         columns=['area', 'gender', 'age', 'height', 'weight'])

union_df = df.append(other_df, ignore_index=True)
```

<img width="282" alt="union_df.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/d6ecc97b-37d2-46a8-bbf0-86354bdd9e34.png">



#基本統計量を算出
numericalなデータを確認するには、基本統計量算出すると、外れ値などのあたりがつくこともある。

```python

df.describe()
```

<img width="267" alt="numerical_data.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/201533/4cd3ffbe-665d-4bff-7484-aa5ea3d6ba7b.png">



#csvの読み込み・書き出し
以下のように、簡単にデータは読み込める。
dfが文字化けしている場合は、encodingを記載する。

```python

df = pd.read_csv('data.csv') 
```

元のcsvにheaderがない場合は、以下のように記載する。

```python

df = pd.read_csv('data.csv', header=None) 
```


以下のように出力も簡単にできる。
ただの連番のindexであれば、出力しないことが多い。

```python

df.to_csv('data.csv', index=False)
```

あまり使わないが、headerも出力しない場合は、以下のように記載する。

```python

df.to_csv('data.csv', header=False, index=False)
```