pandasでよく使う文法まとめ

Pythonのデータ分析用ライブラリ「pandas」でよく使う文法をまとめました．

- Change log

```
2019-02-18　表示拡大の方法を更新
2018-05-06　コメント反映（pd.set_option('display.width', 100)）
2018-02-14　リンクの修正
2017-11-01　df.fillna(method='ffill')の説明を修正
2017-06-09　リンク切れ等の修正
2016-10-10　例の編集
2016-06-21　df.rolling, pd.date_range, pd.datetime, df.pivotの追加，その他の例の追加
```

# **CSVファイルの扱い**

## **pd.read_csv**（読み込み）

多くのオプションが用意されているので，csv以外でもなんでも読み込める．

```py
import pandas as pd

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

例：複数column（`date`と`hour`）をまとめて，datetime型のindex（`date_hour`）として読む場合

```py
df = pd.read_csv('some.csv', parse_dates={'date_hour':['date', 'hour']}, index_col='date_hour')
```

例：日本語の入ったファイル，かつ`--`を欠損データ扱いにする場合

```py
df = pd.read_csv('some.csv', encoding='Shift_JIS', na_values='--')
```

- オプション一覧

|option|意味|
|---|---|
|index_col|indexとするcolumn名|
|parse_dates|datetime型で読み込むcolumn名（リストや辞書）|
|date_parser|parse_datesで指定したcolumnを読み込む自作関数|
|na_values|欠損値とする文字列（リスト）|
|encoding|'Shift_JIS'など|
|sep|区切り文字（' '：スペースの場合）|

- 参考：http://pandas.pydata.org/pandas-docs/stable/generated/pandas.io.parsers.read_csv.html

## **df.to_csv**（書き込み）

恐ろしく簡単にcsvファイルに書き込める．オプションも豊富．

```py
df.to_csv('some2.csv')
```

例：indexがいらない場合

```py
df.to_csv('some2.csv', index=None)
```

例：indexに名前をつける場合

```py
df.to_csv('some2.csv', index_label='date')
```

- 参考：http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.to_csv.html

# **欠損値の扱い**

## **df.dropna**（削除）

欠損値（nan）のある行（index）を削除

```py
df = df.dropna()
```

例：特定のcolumn（`temp`や`depth`）に欠損値がある場合，その行を削除する
（`temp`や`depth`以外の欠損値は無視する）

```py
df = df.dropna(subset=['temp','depth'])
```


## **df.fillna**（穴埋め）

例：定数（0）で穴埋め

```py
df = df.fillna(0)
```

例：前方（後方）穴埋め　（_2017/11/01 @hadacchiのコメントを反映して修正済み_）

```py      
df = df.fillna(method='ffill')  # forward 穴埋め  nan 1.0 nan -> nan 1.0 1.0 （forward  = indexの増加方向 ＝ DataFrameの下方向）
df = df.fillna(method='bfill')  # backward穴埋め  nan 1.0 nan -> 1.0 1.0 nan （backward = indexの減少方向 ＝ DataFrameの上方向）
```
- 参考：https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.fillna.html


## **df.interpolate**（補間）

多くの補間手法が用意されている．

```py
df = df.interpolate(method='index')
```

* method: `linear`, `time`, `index`, `values`, `nearest`, `zero`, `slinear`, `quadratic`, `cubic`, `barycentric`, `krogh`, `polynomial`, `spline`, `piecewise_polynomial`, `pchip`
* datetime型のindexなどの場合，`linear`ではなく`index`にすると良い

- 参考：https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.interpolate.html

## **df.resample**（リサンプル）

時系列データの解像度（頻度）を変更する．
自分が使うときはデータ数を減らすことが多いので圧縮するための関数と認識．

例：1時間毎のデータを日平均に変換（欠損値は無視して平均される）

```py
#daily = hourly.resample('D', how='mean') <- 古い書き方
daily = hourly.resample('D').mean()
```

例：上だと値が 00:00 に配置されるが，12:00 にしたい場合

```py
daily = hourly.resample('D', loffset='12H').mean()
```

### **時間のフォーマット**

|Charactor|意味|備考|
|---|---|---|
|M|月|0.5M で半月とはならない|
|D|日|15D で手を打っている|
|H|時間|12H は12時間|
|T or min|分|30min で30分|

- 参考：http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.resample.html

## **df.rolling**（移動平均）

n項移動平均や最大値などを取る

例：3項移動平均（center=Trueで中央（この場合第2項）に値を配置）

```py
ma3 = hourly.rolling(3, center=True).mean()
```

# **時間の扱い**

## **pd.date_range**

連続したdatetime変数を簡単に作れる

```py
date = pd.date_range('2012-1-1', '2012-1-2', freq='D')
```

例：上のままだとpandasのTimestampなので，pythonのdatetime変数に戻す場合

```py
date = pd.date_range('2012-1-1', '2012-1-2', freq='D').to_pydatetime()
```

## **pd.datetime**

`import datetime`がいらない

```py
date = pd.datetime(2012, 1, 1, 0, 0, 0)
```

# **その他よく使う関数**

## **df.describe**（要約統計量）

各columnのデータ数、平均、分散などの統計量をざっと見る．

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

## **df.groupby**（集約）

columnでグループ化（columnの値をindexとして扱えるように変換）することでデータを扱いやすくする．
stack, unstackよりも判りやすい．

例：複数column（`type`と`time`）でグループ化し、各グループの平均をとる.

```py
grouped_mean = df.groupby(['type','time']).mean()
```

- 参考：http://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.groupby.html

## **df.pivot**（1D→2D）

1次元配列を2次元配列にするイメージ

```py
temp2d = df.pivot(index='y', columns='x', values='temp')
```

# その他のTips

## DataFrameの作成（辞書型）

ファイル以外からDataFrameを作る場合には，辞書を作って読み込ませる．

```py
data = {'a':[0, 1], 'b':[2, 3]}

df = pd.DataFrame(data)
```

例：上の例にindexをつける場合

```py
date = pd.date_range('2012-1-1', '2012-1-2', freq='D')

df = pd.DataFrame(data, index=date)
```

## print時の折り返し幅の拡張

カラム数の多いデータフレームのprint時に表示が折り返されてしまうのが嫌な場合、表示幅を変更できる．

```py
pd.set_option('display.width', 100)
or
pd.set_option('display.max_columns', 100)  # カラム数でも制御できる

#pd.set_option('line_width', 100)  # line_widthは非推奨or廃止（2018/05/06 Thanks to @dhwty）

print df  # 100文字（or カラム）まで折り返されない
```

# 参考になるリンク

* [pandas document] (http://pandas.pydata.org/pandas-docs/stable/)
* [pandas によるデータセットの加工 (1)](http://qiita.com/ynakayama/items/2769bc92bb71ebf23be6) @ynakayama
* [pandasメモ] (http://qiita.com/airtoxin/items/d66a22c5c7074e23be17) @airtoxin
* [Pandasでデータフレームを条件指定で参照する](http://qiita.com/wwacky/items/095bcac7cc450dc3232a) @wwacky