[python] pandasでqueryを用いた条件抽出 

# はじめに
pandasで無数のデータを扱う場合、条件を満たす値だけを取り出す必要がある
例えば、一定の費用以上のプロジェクトだけを探したい時、一定期間の日付のリストを探したい時、などなど
ここではpandas でqueryを用いて必要な値を持つデータフレームに絞ることを紹介する

前回の記事
[[python] 複雑なエクセルデータをpandasで処理する](https://qiita.com/junzai/items/fd626f8a71a15cabd91a)

# 環境
python 3.7.8
window 10



# Code 

```python
import pandas as pd

df = pd.read_excel('./data.xlsx')
df
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/91ba8334-9069-8bc5-11a2-2f45fac1c0f9.png)

## 単一条件
一つの列にたいしての条件でデータを絞ることができる。
### 変数名で抽出

Name列がTanakaである
```python
df.query("Name == 'Tanaka'")
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/50a56231-38d2-1c28-7edd-680fb8a43b77.png)

Class列がBではない
```python
df.query('Class != "B"')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/afe29266-4982-c916-03ee-90bb25c415f6.png)

### 変数の範囲で抽出

Point列が50より高い
```python
df.query('Point > 50')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/e15cfe10-8d0a-1b0f-4feb-dc0cbdf8507f.png)

Point列が90である
```python
df.query('Point == 90')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/e424ccc7-fa7b-375d-70e5-39de9306dcae.png)

### インデックスの範囲で抽出
インデックスが2以上である
```python
df.query('index >= 2')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/dd3689a0-938a-a65f-ff0b-be9f57a9a83e.png)

インデックスが偶数である
```python
df.query('index%2 == 0')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/3ca174b5-9a03-3630-5e90-fbf4650ca49d.png)


## 複数条件

### 変数の条件で抽出
Point列が50以上 または Class列がBである
```python
df.query('Point >= 50 or Class == "B"')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/fbbc24a2-639c-5c18-9db3-ca4090f55f08.png)

Point列が50以上 かつ Class列がBである

```python
df.query('Point >= 50 and Class == "B"')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/bda92543-7561-4177-4c9b-577fbcef7c61.png)

Point列が50以上 かつ 60より小さい値である
```python
df.query(' 50 <= Point < 60')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/6f41421e-b406-ac12-8e49-de4e3b411a00.png)

### リストの中の値を持つ条件
Class列に"A" 、"B"を含む
```python
df.query('Class in ["A", "B"]')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/f645070c-d923-a720-82dc-ab6a40e8b435.png)
Class列に90 、55を含む
```python
df.query('Point in [90, 55]')
```

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/0462162b-55a4-c01a-2ef5-f25fc21b9369.png)

Class列に90、55を含まない
```python
df.query('Point not in [90, 55]')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/af9add34-5b54-0888-fb1c-907effbef52a.png)


## 変数を使用した条件
変数の前に@につけて用いる   
   
```python
x = 90
df.query('Point == @x')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/d462fd85-0888-e841-25b9-2c4e9fdaf191.png)

```python
y = [50, 30]
df.query('Point in @y')
```
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2821152/6f6b8d64-b9b0-e65a-0bb8-d0c29c83b199.png)


# まとめ
pandas の queryを用いることによってデータフレームのほとんどは値を絞ることができる。
前回でも紹介したように、複雑なデータでもとりあえずデータフレームの行列の形にできてしまえば、条件付きでより洗練されたデータを得ることができる。


[pandas.DataFrame.query公式ドキュメント](https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.query.html)