Pandasのよく使う機能まとめ

業務でデータ解析する時にPythonとPandasを使うと凄く楽だな～と思ったので、よく使う機能を備忘録的にまとめてみる

# 準備
## インストール
とりあえずPandasがないと始まらないので、インストールする。

```
pip install pandas
```

僕は使っていないが、Anacondaだと最初から入っているらしい。

## インポート

Pythonコード中に下記の通りインポートする。

```python
import pandas as pd
```

慣例的に`pd`という名前で置換するらしい。


# csvから読み込み

以下のようなcsvファイルを作ってインポートしてみる。

|Time|col1|col2|col3|
|:--|:--|:--|:--|
|12:00:00|0|A|123|
|12:05:00|0|AA|456|
|12:10:00|1|AB|789|
|12:15:00|1|BB|111|
|12:20:00|0|C|222|
|12:25:00|0|D|333|

`read_csv()`という関数にcsvへのパスを渡すだけでデータフレームのインスタンスを返してくれる。

```python
df = pd.read_csv("csvへのパス")
```

例のcsvをカレントに`hoge.csv`という名前で保存したとすると、以下のようになる

![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/5eff58ce-8daf-aba1-c1bc-6304cdbbb38e.png)

ここで、csvファイルの文字コードが`utf-8`以外だと、デフォルトではエラーになる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/fb9cfb15-0544-8bef-0dca-3c274861884f.png)
こういう場合は、ファイルの文字コードに合わせて引数`encoding`に指定すると読めるようになる。

```python
df = read_csv("csvへのパス", encoding="文字コード")
```

![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/f21815d8-1ec8-71ec-fbe4-c91adef1f9bb.png)

## 行をインデックスに指定して読み込み

何も指定せず`read_csv`で読み込むと、行番号を自動的に連番で振ってくれるが、csvファイル中に行のインデックスに該当する列がある場合は、それを指定することもできる。

```python
df = read_csv("csvへのパス", index_col="インデックスにする列名")
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/4a85dc34-a358-5846-38cb-100d74947e52.png)

固有のIDやログファイルの時刻列等、指定できると便利なシチュエーションは結構ある。

## 任意のヘッダを設定して読み込み

何も指定せず`read_csv`で読み込むと、1行目をヘッダとして読み込まれるが、ファイルにヘッダ行がない場合やファイルのヘッダと異なるヘッダ名にしたい時は、それを指定することもできる。

### ヘッダ行を指定する場合

あまりないシチュエーションだが、ファイルの先頭以外にヘッダ行がある場合(2行目以前が不良行)は、引数`header`にヘッダの行番号を指定すると、指定行をヘッダとして以降の行を読み込む。

```python
df = read_csv("csvへのパス", header=行番号)
```


### ヘッダ行がない場合

シチュエーション的にはこちらのほうが多い。ファイル中にデータ行しかない場合は、引数`header`に`None`を設定するとヘッダなしで読み込む。

```python
df = read_csv("csvへのパス", header=None)
```

この場合は、自動的にヘッダに連番を振ってくれる。

# Excelファイルの読み込み

`read_csv`のようにExcelファイル`xls`,`xlsx`も読み込める。

```python
df = read_excel("xlsx/xlsへのパス")
```
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/a68dbaf6-654c-8e23-52c2-a56a2857155e.png)

ただし`xlrd`という別のモジュールが必要なので、インストールしていないと下記のようなエラーが出る。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/dab49533-5ee3-7ab5-4431-1efcb1720331.png)
この場合は普通に`xlrd`をインストールすればよい。

```
pip install xlrd
```
## シートの指定

オプション引数の`sheet_name`にシート名orシート番号を指定することで、読み込むシートを指定できる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/40689d89-37d8-d3ff-cba0-7b66f3078482.png)
ちなみに、未指定だと自動的に1シート目になる。

## 他のよく使うオプション

### ヘッダ指定

`read_csv`同様、ヘッダを指定できる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/5298a395-38d6-aa42-4267-41de47405765.png)

### インデックス指定

インデックスも`read_csv`同様に指定できる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/87d88aab-f22f-18e3-caf7-b787b09b1be5.png)

# データ抽出

## 所定の列だけ抽出

データフレームから列を指定して抽出するには、`データフレーム名[列名]`で指定すればよい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/eb1360e2-90ed-6bd7-b859-10e1bfb2b778.png)
1列だけなので、DataFrameからSeriesに自動で変換される。
列名の指定にリスト形式で複数の列を指定することもできる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/f4cc51bf-0011-dbfa-64df-1ffd5aba4224.png)
この場合は複数列なので、DataFrameのままになる。

## 所定の行だけ抽出

データフレームから行を指定して抽出するには、`データフレーム名.loc[インデックス]`で指定すればよい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/2838ec26-e9a9-1293-5f9b-4c4faa7c03cc.png)
1行だけなので、DataFrameからSeriesに自動で変換される。
列同様、リスト形式で複数の行を指定することもできる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/4a008994-6217-da0c-d931-1b8b846d368a.png)
この場合は複数列なので、DataFrameのままになる。

## 行も列も指定して抽出

行指定と同じ、`データフレーム名.loc[抽出行インデックス, 列名]`で行も列も自由に取れる。標準のリスト同様にスライスも指定できるのでインデックスとカラムを把握していれば、範囲指定抽出は簡単にできる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/5a7183cc-7dc8-4dd1-2166-747de2ce7a61.png)
行・列を1つずつ指定すると、インデックス名・カラム名にかぶりがない限り、該当データ1件を取り出せる。この用途の場合は`データフレーム名.at[抽出行インデックス, 列名]`という指定方法もあり、`.at`の方が処理が早いらしい。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/7f1b8eea-9605-205a-a178-af1f79c2fb2e.png)
行名・列名ではなく、行番・列番で指定することもできる。この場合は`.loc`や`.at`に**i**をつけて`.iloc`や`.iat`で指定する。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/3799caf5-5879-f4e0-4896-c2d287086384.png)
通常のスライスが使えるので、`.iloc`を利用すると偶数行・奇数行の抽出が簡単にできる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/c5ac43e0-a4f8-61c6-e4af-6eb0d9f21e89.png)

## 条件を指定して抽出

`.loc`にbool値のリストを渡すと、Trueの行や列だけを抽出することができる。これを利用して、データフレームやシリーズの条件を`.loc`内に記述すると条件抽出ができる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/ad3a9048-08f5-82cd-2b20-7e2f64437b17.png)
データフレームには、`query()`というメソッドもあり、引数に条件を文字列で渡すことでも抽出が可能。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/3bef37e7-942a-3dc3-7ad2-0773838db3da.png)
変数値を使う場合は、条件分中に`@`をつけることで参照できる。
![image.png](https://qiita-image-store.s3.amazonaws.com/0/291298/959cf6cb-c195-02b6-da04-02dbf20b5b7c.png)

# 終わりに
外部モジュールを積極使用しすぎると、PythonのバージョンUP等で不具合が出たりする可能性があるので、外部モジュールをむやみに使わないポリシーでやっていた。しかし、自作クラスなどでPython上だけでいくら頑張っても、工数面でもパフォーマンス面でもPandasにかなわないので、Pandasのような超有名どころの外部モジュールは使っちゃったほうがいいかなぁと思った次第。