Python/pandasでの条件検索チートシート（query、loc、filter等）

# はじめに
pandasでqueryによるDataFrameの検索を行う場合の記載について、チートシートを作成したかった。
実現方法はいろいろあるが、独断と偏見で使いやすいなと思った方法を記載。
毎回混乱するので営為作成中。随時更新していく予定。
調べながら作っているので違っているところ多数あるかも。

なお、以下サイト曰く、
処理時間や性能を考える場合は、下手に関数を使わないほうが早いらしい。
[クラウドエンジニアのノート]https://tmyoda.hatenablog.com/entry/2020/03/13/185319)

```python:Python
#queryでpriceが300であるものを検索　→　もちろん動く
df.query('price==300')

#直接priceが300であるものを検索　→　動くし、早い
df[df['price'] == 300]
```



# まとめ 
| 抽出条件 | 行名(インデックス） | 列名 | 値|
|:-----------|:------------|:------------|:------------|
| ある値に一致するものを抽出 | df.loc <br> df.filter <br> df.query | df.loc <br> df.filter | df.query |
| ある値と一致しないものを抽出 | df.drop <br> df.filter <br> df.query | df.drop <br> df.filter | df.query |
| あいまい検索 | df.query <br> df.filter | df.filter | df.query |
| 大小指定（不等号） | df.query | - | df.query |
| 定義した関数を利用 | df.query | - | df.query |

こうしてまとめてみるとquery最強。
インデックスと値はqueryでまかなえ、列名を対象とするときloc、drop、filterを使うイメージか。
結局queryは関数や正規表現を利用できるところから、万能感はある。



# サンプルコードの前提DF
```python:Python
import pandas as pd
import numpy as np
df = pd.DataFrame({"Name":['田中', '鈴木', '小林', '藤原'],
                   "Mt":[55, 60, 30, np.nan],
                   "Jp":[70, 40, 65, 55],
                   "Sc":[np.nan, 95, np.nan, np.nan],
                   "So":[38, 47, 61, 82]}).set_index("Name")


# 		Mt		Jp		Sc		So
# Name				
# 田中	54.0	70.0	NaN		NaN
# 鈴木	60.0	40.0	95.0	47.0
# 小林	30.0	NaN		NaN		61.0
# 藤原	NaN		55.0	NaN		82.0
```

# loc
行名、列名を指定し抽出することができる

```python:Python
df.loc[['田中','鈴木'],:]

#		Mt		Jp		Sc		So
# Name				
# 田中	54.0	70.0	NaN		NaN
# 鈴木	60.0	40.0	95.0	47.0
```

```python:Python
df.loc[:,['Mt', 'Sc']]

# 		Mt		Sc
# Name		
# 田中	54.0	NaN
# 鈴木	60.0	95.0
# 小林	30.0	NaN
# 藤原	NaN		NaN
```

# drop
行名、列名を指定し、指定したもの以外を残し抽出することができる
```python:Python
df.drop(index= ['小林', '藤原'])

# 		Mt		Jp		Sc		So
# Name				
# 田中	54.0	70.0	NaN		NaN
# 鈴木	60.0	40.0	95.0	47.0
```

```python:Python
df.drop(columns= ['Mt', 'Sc'])

#		Jp		So
# Name		
# 田中	70.0	NaN
# 鈴木	40.0	47.0
# 小林	NaN		61.0
# 藤原	55.0	82.0
```

# filter
行名、列名を指定し抽出。
正規表現やlikeが利用できる点が特徴。完全一致ならlocやdropと同じ。

```python:Python
df.filter(items=['田中','鈴木'], axis=0)

#		Mt		Jp		Sc		So
# Name				
# 田中	54.0	70.0	NaN		NaN
# 鈴木	60.0	40.0	95.0	47.0
```
```python:Python
df.filter(items=['Mt','Sc'])

# 		Mt		Sc
# Name		
# 田中	54.0	NaN
# 鈴木	60.0	95.0
# 小林	30.0	NaN
# 藤原	NaN		NaN
```
```python:Python
df.filter(like='S')

# 		Sc		So
# Name		
# 田中	NaN		NaN
# 鈴木	95.0	47.0
# 小林	NaN		61.0
# 藤原	NaN		82.0
```
```python:Python
df.filter(regex="中$", axis=0)

# 		Mt		Jp		Sc		So
# Name				
# 田中	54.0	70.0	NaN		NaN
```

# query
自由度という面では万能。

```python:Python
df.query("Name == '田中'")

# 		Mt		Jp		Sc		So
# Name				
# 田中	54.0	70.0	NaN		NaN
```
```python:Python
df.query("Name in ['田中', '山田']")

# 		Mt		Jp		Sc		So
# Name				
# 田中	54.0	70.0	NaN		NaN


df.query("Name not in ['田中', '山田']")

#		Mt		Jp		Sc		So
# Name				
# 鈴木	60.0	40.0	95.0	47.0
# 小林	30.0	NaN		NaN		61.0
# 藤原	NaN		55.0	NaN		82.0
```
```python:Python
df.query("Sc.isna()", engine='python')

# 		Mt		Jp		Sc		So
# Name				
# 田中	54.0	70.0	NaN		NaN
# 小林	30.0	NaN		NaN		61.0
# 藤原	NaN		55.0	NaN		82.0


df.query("Sc.notna()", engine = 'python')

# 		Mt		Jp		Sc		So
# Name				
# 鈴木	60.0	40.0	95.0	47.0
```
```python:Python
df.query('Jp > 50')

# 		Mt		Jp		Sc		So
# Name						
# 田中	54.0	70.0	NaN		NaN
# 藤原	NaN		55.0	NaN		82.0
```
```python:Python
df.query('index.str.contains("田")', engine='python')

# 		Mt		Jp		Sc		So
# Name						
# 田中	54.0	70.0	NaN		NaN


df.query('index.str.match("^田")', engine='python')

# 		Mt		Jp		Sc		So
# Name						
# 田中	54.0	70.0	NaN		NaN

```