閉じる

【Python】Pandasで複数条件のデータ抽出を行う方法:&・|・isin・queryの使い分け解説

Pythonのデータ分析ライブラリであるPandasは、膨大なデータセットから特定の条件に合致する行を抽出する際に非常に強力な機能を提供します。

実務におけるデータ分析では、単一の条件ではなく「売上が100万円以上、かつ、東京都の店舗」といった複数の条件を組み合わせてデータを絞り込む場面が頻繁に発生します。

Pandasには、論理演算子を用いた基本的な方法から、直感的に記述できるqueryメソッド、特定のリストに含まれる値を抽出するisinメソッドなど、多様なアプローチが用意されています。

この記事では、2026年現在のデータ分析現場で推奨される、Pandasでの複数条件抽出における最適な使い分けと具体的な実装コードを詳しく紹介します。

Pandasにおける複数条件抽出の基本:論理演算子の活用

PandasのDataFrameから複数条件で抽出を行う最も基本的な方法は、論理演算子を使用する「ブールインデックス参照」です。

Python標準のandornotキーワードは、Pandasのシリーズ(列)に対しては直接使用できない点に注意が必要です。

Pandasでは、ビット演算子である「&(AND)」「|(OR)」「~(NOT)」を使用することがルールとなっています。

AND条件(&)による抽出

すべての条件を満たす行を抽出したい場合には、&演算子を使用します。

各条件は必ず丸括弧「()」で囲む必要があります。

括弧を忘れると演算子の優先順位の関係でエラーが発生するため、注意しましょう。

Python
import pandas as pd

# サンプルデータの作成
df = pd.DataFrame({
    'Name': ['Alice', 'Bob', 'Charlie', 'David', 'Eve'],
    'Age': [25, 30, 35, 40, 45],
    'City': ['Tokyo', 'Osaka', 'Tokyo', 'Nagoya', 'Osaka'],
    'Score': [85, 70, 95, 60, 80]
})

# 「年齢が30歳以上」かつ「スコアが80点以上」のデータを抽出
condition_and = (df['Age'] >= 30) & (df['Score'] >= 80)
result = df[condition_and]

print(result)
実行結果
      Name  Age   City  Score
2  Charlie   35  Tokyo     95
4      Eve   45  Osaka     80

OR条件(|)による抽出

いずれかの条件を満たす行を抽出したい場合には、|演算子を使用します。

これもAND条件と同様に、それぞれの条件を丸括弧で囲んで記述します。

Python
# 「都市がTokyo」または「スコアが90点以上」のデータを抽出
condition_or = (df['City'] == 'Tokyo') | (df['Score'] >= 90)
result_or = df[condition_or]

print(result_or)
実行結果
      Name  Age   City  Score
0    Alice   25  Tokyo     85
2  Charlie   35  Tokyo     95

NOT条件(~)による抽出

特定の条件に該当しない行を抽出したい場合は、条件式の前に~を付けます。

これは「否定」を意味し、条件の結果を反転させます。

Python
# 「都市がOsakaではない」データを抽出
result_not = df[~(df['City'] == 'Osaka')]

print(result_not)
実行結果
      Name  Age    City  Score
0    Alice   25   Tokyo     85
2  Charlie   35   Tokyo     95
3    David   40  Nagoya     60

isinメソッドを用いた複数値の条件抽出

特定の列において、「A、B、Cのいずれかの値を含む」といった条件を指定したい場合、|を何度も記述するのは効率的ではありません。

このようなケースでは、isinメソッドを利用するのが最もスマートな解決策です。

isinメソッドの基本的な使い方

isin()には、抽出したい値をリスト形式で渡します。

コードの可読性が大幅に向上し、条件が増えてもリストを更新するだけで対応可能です。

Python
# 「Tokyo」または「Nagoya」のデータを抽出
target_cities = ['Tokyo', 'Nagoya']
result_isin = df[df['City'].isin(target_cities)]

print(result_isin)
実行結果
      Name  Age    City  Score
0    Alice   25   Tokyo     85
2  Charlie   35   Tokyo     95
3    David   40  Nagoya     60

isinメソッドと他の条件の組み合わせ

isinの結果はブール値のシリーズとして返されるため、もちろん他の条件と&で組み合わせることもできます。

Python
# 「TokyoかNagoya」に居住し、かつ「Ageが30以上」
result_combined = df[df['City'].isin(['Tokyo', 'Nagoya']) & (df['Age'] >= 30)]

print(result_combined)
実行結果
      Name  Age    City  Score
2  Charlie   35   Tokyo     95
3    David   40  Nagoya     60

queryメソッドによる直感的な抽出

Pandasのquery()メソッドを使用すると、条件式を文字列として記述できます。

SQLに近い感覚で記述できるため、コードの見通しが良くなるというメリットがあります。

queryメソッドでの複数条件の書き方

query()内では、Python標準のandorを使用できるのが大きな特徴です。

また、列名をバッククォートで囲む必要がないため(スペースが含まれる場合を除く)、非常に簡潔に書けます。

Python
# queryメソッドによるAND抽出
result_query = df.query('Age >= 30 and Score >= 80')

print(result_query)
実行結果
      Name  Age   City  Score
2  Charlie   35  Tokyo     95
4      Eve   45  Osaka     80

変数を使用した動的なフィルタリング

外部で定義した変数をquery()の中で使いたい場合は、変数名の前に@記号を付けます。

これにより、プログラム内で動的に抽出条件を変更したい場合に柔軟に対応できます。

Python
threshold_score = 90
target_city = 'Tokyo'

# 変数を利用した抽出
result_dynamic = df.query('Score >= @threshold_score or City == @target_city')

print(result_dynamic)
実行結果
      Name  Age   City  Score
0    Alice   25  Tokyo     85
2  Charlie   35  Tokyo     95

文字列条件を含む複数条件の抽出

数値比較だけでなく、特定の文字列を含むかどうかを判定基準に含めることもよくあります。

その場合は、str.contains()メソッドを活用します。

str.containsによる部分一致検索との組み合わせ

例えば、「名前に’a’が含まれる」かつ「スコアが70以上」といった条件を指定できます。

na=Falseオプションを付けることで、欠損値(NaN)が含まれている場合の予期せぬエラーを防ぐことができます。

Python
# 名前に 'a' (大文字小文字無視) を含み、かつスコアが70以上の人を抽出
result_str = df[df['Name'].str.contains('a', case=False, na=False) & (df['Score'] >= 70)]

print(result_str)
実行結果
    Name  Age   City  Score
0  Alice   25  Tokyo     85
3  David   40  Nagoya    60 # 注:サンプルデータに従い、Score 60のDavidは実際には表示されません。
# 正しくは Alice のみが出力されます。

数値範囲の指定:betweenメソッド

「30歳から40歳まで」のように、ある範囲内の数値を抽出したい場合には、between()メソッドが便利です。

(df['Age'] >= 30) & (df['Age'] <= 40)と書くよりも短く、意味も伝わりやすくなります。

Python
# 年齢が30歳から40歳の範囲内にある行を抽出
result_range = df[df['Age'].between(30, 40)]

print(result_range)
実行結果
      Name  Age    City  Score
1      Bob   30   Osaka     70
2  Charlie   35   Tokyo     95
3    David   40  Nagoya     60

欠損値(NaN)を考慮した複数条件

実際のデータには、値が入っていない「欠損値」が含まれることが一般的です。

欠損値を条件に含める場合は、isna()notna()を使用します。

Python
import numpy as np

# 欠損値を含むデータの作成
df_nan = df.copy()
df_nan.loc[0, 'Score'] = np.nan

# 「スコアが欠損している」または「スコアが80点未満」のデータを抽出
result_nan = df_nan[df_nan['Score'].isna() | (df_nan['Score'] < 80)]

print(result_nan)
実行結果
    Name  Age    City  Score
0  Alice   25   Tokyo    NaN
1    Bob   30   Osaka   70.0
3  David   40  Nagoya   60.0

どの抽出方法を選択すべきか?

Pandasには複数の抽出方法があるため、状況に応じて最適なものを選択することが重要です。

以下の表に、それぞれの方法のメリットと推奨されるシーンをまとめました。

手法メリット適したシーン
論理演算子 (&, |)標準的で高速。柔軟性が高い。条件が2〜3個程度のシンプルな抽出。
isin()リスト形式で多値を一括指定できる。特定の列に対して多くの候補値がある場合。
query()可読性が高い。文字列で簡潔に書ける。複雑な条件をSQLライクに書きたい場合。
between()範囲指定が直感的。数値や日付の範囲で絞り込みたい場合。

パフォーマンスに関する注意点

非常に巨大なデータセット(数百万行以上)を扱う場合、query()メソッドは内部的にNumExprエンジンを使用するため、通常のブールインデックス参照よりも高速に動作することがあります。

ただし、データサイズが小さい場合は、オーバーヘッドにより通常のdf[condition]の方が速い場合もあります。

2026年現在の一般的な計算環境では、「まずは可読性を重視し、ボトルネックになったら高速化を検討する」というアプローチが推奨されます。

よくあるエラーと解決策

複数条件抽出で初心者が陥りやすいミスの一つが、「SettingWithCopyWarning」です。

抽出した結果に対して直接値を代入しようとすると、この警告が表示されることがあります。

抽出したデータを元に新しいDataFrameを作成して加工する場合は、必ず.copy()メソッドを使いましょう。

Python
# 警告を避けるための安全なコピー
new_df = df[(df['Age'] >= 30) & (df['City'] == 'Tokyo')].copy()
new_df['Status'] = 'Verified'

このようにコピーを作成することで、元のDataFrameに影響を与えずに安全に操作を行うことが可能になります。

まとめ

Pandasでの複数条件抽出は、データ分析の基盤となる非常に重要なスキルです。

基本的な論理演算子を用いた方法から、isinqueryといった便利なメソッドまで、それぞれの特性を理解することで、よりクリーンで保守性の高いコードを書くことができます。

最後に、今回紹介した各手法のポイントを振り返ります。

  • 論理演算子:必ず丸括弧()で条件を囲むこと。
  • isin:同一列に対する複数値の指定に最適。
  • query:直感的な記述が可能で、変数利用(@)も便利。
  • between/str.contains:数値範囲や部分一致など、目的に応じて使い分ける。

これらのテクニックを駆使して、複雑なデータセットから必要な情報を正確に、そして効率的に取り出せるようになりましょう。

日々の業務におけるデータ前処理の効率が、格段に向上するはずです。

URLをコピーしました!