Pandas DataFrame query()メソッドで条件抽出を簡単に!使い方とサンプルコード集

 

PandasのDataFrameで条件に基づいてデータを抽出する際、query()メソッドは非常に便利で直感的な方法です。従来のブール indexingと比べて、より読みやすく簡潔にコードを書くことができます。この記事では、query()メソッドの基本的な使い方から応用テクニックまでを詳しく解説します。

query()メソッドとは

query()メソッドは、DataFrameに対して条件式を文字列として指定し、その条件に合う行を抽出するPandasの機能です。SQLのWHERE句のような感覚で使用でき、複雑な条件も直感的に記述できます。

基本的な構文

df.query('条件式')

基本的な使い方

まずは簡単なDataFrameを作成して、基本的な使用方法を見てみましょう。

import pandas as pd

# サンプルデータの作成
df = pd.DataFrame({
    'name': ['田中', '佐藤', '鈴木', '高橋', '伊藤'],
    'age': [25, 30, 35, 28, 32],
    'score': [85, 92, 78, 88, 95]
})

単一条件での抽出

# 年齢が30以上の行を抽出
result = df.query('age >= 30')
print(result)

文字列条件での抽出

# 名前が '佐藤' の行を抽出
result = df.query('name == "佐藤"')
print(result)

複数条件での抽出

AND条件(&または and)

# 年齢が25以上かつスコアが90以上
result = df.query('age >= 25 and score >= 90')
# または
result = df.query('age >= 25 & score >= 90')

OR条件(|または or)

# 年齢が25以下または35以上
result = df.query('age <= 25 or age >= 35')
# または
result = df.query('age <= 25 | age >= 35')

NOT条件(~または not)

# 名前が '田中' ではない行
result = df.query('name != "田中"')
# または
result = df.query('not name == "田中"')

応用的な使い方

変数を使った条件指定

外部の変数を条件に使用する場合は、@記号を使用します。

min_age = 30
max_score = 90

# 変数を使った条件指定
result = df.query('age >= @min_age and score <= @max_score')

リストを使った条件指定(isin)

target_names = ['田中', '佐藤', '鈴木']

# 指定した名前のリストに含まれる行を抽出
result = df.query('name in @target_names')

範囲指定

# 年齢が25から30の間の行を抽出
result = df.query('25 <= age <= 30')

文字列の部分一致

# サンプルデータに都市列を追加
df['city'] = ['東京', '大阪', '東京', '名古屋', '大阪']

# 都市名に '東' が含まれる行を抽出
result = df.query('city.str.contains("東")')

query()メソッドの利点

可読性の向上

従来のブールインデックスと比較してみましょう。

# 従来の方法(ブールインデックス)
result = df[(df['age'] >= 30) & (df['score'] >= 85)]

# query()メソッド使用
result = df.query('age >= 30 and score >= 85')

query()メソッドの方が、条件が直感的で読みやすくなっています。

メソッドチェーンでの使用

# メソッドチェーンでの使用例
result = (df.query('age >= 30')
           .query('score >= 85')
           .sort_values('score', ascending=False))

よくあるエラーと対処法

カラム名にスペースが含まれる場合

# カラム名にスペースがある場合はバッククォートで囲む
df_space = df.copy()
df_space.columns = ['name', 'age group', 'test score']

result = df_space.query('`age group` >= 30')

欠損値の処理

# 欠損値を含むデータでの条件指定
df_nan = df.copy()
df_nan.loc[1, 'age'] = None

# 欠損値を除外して条件指定
result = df_nan.query('age >= 30')  # 自動的にNaNは除外される

パフォーマンスの考慮点

大きなデータセットでは、query()メソッドはnumexprライブラリを使用して高速化されます。

# 大きなデータセットでの使用例
large_df = pd.DataFrame({
    'col1': range(1000000),
    'col2': range(1000000)
})

# 複雑な条件でも高速に処理
result = large_df.query('col1 > 500000 and col2 < 800000')

まとめ

query()メソッドは、PandasのDataFrameで条件抽出を行う際の強力なツールです。特に以下の場面で威力を発揮します:

  • 複雑な条件を直感的に記述したい場合
  • メソッドチェーンでデータ処理を連続して行いたい場合
  • 外部変数を条件に使用したい場合
  • 大量データでの高速な条件抽出が必要な場合

従来のブールインデックスと使い分けることで、より効率的で読みやすいPandasコードを書くことができるようになります。