この記事で分かること:
• pandasで複数条件を指定する基本的な方法
• AND条件・OR条件の正しい書き方
• queryメソッドとlocの使い分け
• よくあるエラーと対処法
pandasでデータ分析をしていると「複数の条件を同時に満たす行だけを抽出したい」という場面が頻繁に出てきます。この記事では、pandas初心者でも理解できるよう、具体例を交えながら複数条件でのデータ抽出方法を徹底解説します。
pandasで複数条件を使う基本(AND・OR)
pandasで複数条件を指定する際は、必ず各条件を括弧で囲むことが重要です。
基本的な書き方
AND条件(&):すべての条件を満たす行を抽出
import pandas as pd # サンプルデータの作成 df = pd.DataFrame({ 'name': ['田中', '佐藤', '鈴木', '高橋', '伊藤'], 'age': [25, 30, 35, 40, 28], 'salary': [400, 500, 600, 700, 450], 'department': ['営業', 'IT', '営業', '管理', 'IT'] }) # 年齢が30以上かつ給与が500以上の社員を抽出 result = df[(df['age'] >= 30) & (df['salary'] >= 500)] print(result)
OR条件(|):いずれかの条件を満たす行を抽出
# 年齢が25以下または給与が600以上の社員を抽出 result = df[(df['age'] <= 25) | (df['salary'] >= 600)] print(result)
⚠️ 重要な注意点:
- 各条件は必ず括弧で囲む:
(df['age'] >= 30)
- AND条件には
&
を使用(and
ではない) - OR条件には
|
を使用(or
ではない)
複数条件と括弧の優先順位
3つ以上の条件を組み合わせる場合、括弧の使い方で結果が変わります。
# 例1:(A または B) かつ C result1 = df[((df['age'] <= 30) | (df['salary'] >= 600)) & (df['department'] == '営業')] # 例2:A または (B かつ C) result2 = df[(df['age'] <= 30) | ((df['salary'] >= 600) & (df['department'] == '営業'))]
💡 可読性を高めるコツ:
- 長い条件は変数に分けて記述
- 改行を使って見やすくする
# 可読性の高い書き方 young_condition = df['age'] <= 30 high_salary_condition = df['salary'] >= 600 sales_condition = df['department'] == '営業' result = df[ (young_condition | high_salary_condition) & sales_condition ]
locとqueryの違い・使い分け
pandasで複数条件を指定する方法は主に2つあります:loc
とquery
メソッドです。
比較表
項目 | loc | query |
---|---|---|
書き方 | Python構文そのまま | 文字列ベース |
可読性 | 複雑になりがち | 直感的で読みやすい |
パフォーマンス | 高速 | やや低速(大きなデータでは差が出る) |
変数利用 | 直接利用可能 | @記号が必要 |
loc を使った複数条件指定
# locを使った基本的な書き方 result = df.loc[(df['age'] >= 30) & (df['salary'] >= 500)] # 特定の列のみを抽出 result = df.loc[(df['age'] >= 30) & (df['salary'] >= 500), ['name', 'age']]
query を使った複数条件指定
# queryを使った基本的な書き方 result = df.query('age >= 30 & salary >= 500') # より複雑な条件 result = df.query('age >= 30 & salary >= 500 & department == "営業"') # 変数を使う場合(@記号を使用) min_age = 30 result = df.query('age >= @min_age')
🔍 使い分けの指針:
- query推奨:条件が複雑で可読性を重視する場合
- loc推奨:パフォーマンスを重視する場合、変数を多用する場合
よくあるエラーと対処法
pandas初心者が複数条件で躓きがちなエラーと解決方法を解説します。
1. ValueError: The truth value of a Series is ambiguous
エラーの原因:括弧を忘れてand
やor
を使用
# ❌ エラーが発生する書き方 # result = df[df['age'] >= 30 and df['salary'] >= 500] # エラー! # ✅ 正しい書き方 result = df[(df['age'] >= 30) & (df['salary'] >= 500)]
2. 括弧不足によるエラー
# ❌ 括弧が不足している # result = df[df['age'] >= 30 & df['salary'] >= 500] # エラー! # ✅ 各条件を括弧で囲む result = df[(df['age'] >= 30) & (df['salary'] >= 500)]
3. NaN値が含まれる場合の注意点
# NaN値を含むサンプルデータ df_with_nan = df.copy() df_with_nan.loc[0, 'age'] = None # NaN値は条件に一致しない result = df_with_nan[(df_with_nan['age'] >= 30) & (df_with_nan['salary'] >= 500)] # NaN値を除外してから条件指定 result = df_with_nan.dropna().loc[(df_with_nan.dropna()['age'] >= 30) & (df_with_nan.dropna()['salary'] >= 500)]
実用的な複数条件パターン集
実際のデータ分析でよく使われる複数条件のパターンを紹介します。
数値範囲での抽出
# 年齢が25歳以上35歳以下の社員 result = df[(df['age'] >= 25) & (df['age'] <= 35)] # betweenメソッドを使った書き方(両端含む) result = df[df['age'].between(25, 35)] # betweenメソッドで片端除外 result = df[df['age'].between(25, 35, inclusive='left')] # 25<=age<35
複数値の一致(isin)
# 特定の部署の社員を抽出 target_departments = ['営業', 'IT'] result = df[df['department'].isin(target_departments)] # 複数条件とisinの組み合わせ result = df[(df['age'] >= 30) & (df['department'].isin(target_departments))]
文字列条件の複数指定
# 名前に特定の文字を含む社員(サンプルデータを拡張) df_extended = pd.DataFrame({ 'name': ['田中太郎', '佐藤花子', '鈴木一郎', '高橋美咲', '伊藤健太'], 'age': [25, 30, 35, 40, 28], 'email': ['tanaka@example.com', 'sato@example.com', 'suzuki@gmail.com', 'takahashi@example.com', 'ito@yahoo.com'] }) # 名前に「太郎」を含み、メールアドレスが「example.com」で終わる result = df_extended[ (df_extended['name'].str.contains('太郎')) & (df_extended['email'].str.endswith('example.com')) ]
否定条件(NOT)
# チルダ(~)を使った否定条件 # 営業部でない社員 result = df[~(df['department'] == '営業')] # 複数条件での否定 # 年齢30未満でかつ営業部でない社員 result = df[(df['age'] < 30) & ~(df['department'] == '営業')]
パフォーマンス改善のコツ
大きなデータセットで複数条件を扱う際のパフォーマンス改善方法を紹介します。
1. Boolean indexingの最適化
# 条件を変数に格納してからフィルタリング age_condition = df['age'] >= 30 salary_condition = df['salary'] >= 500 department_condition = df['department'] == '営業' # 一度に全条件を評価 final_condition = age_condition & salary_condition & department_condition result = df[final_condition]
2. queryメソッドの活用
# 複雑な条件はqueryメソッドが高速な場合がある result = df.query('age >= 30 & salary >= 500 & department == "営業"') # 数値計算を含む条件 result = df.query('age * 1.1 > 33 & salary / age > 15')
3. データ型の最適化
# カテゴリ型に変換してメモリ使用量とパフォーマンスを改善 df['department'] = df['department'].astype('category') # 整数型の最適化 df['age'] = df['age'].astype('int8') # 年齢は0-255で十分
応用テクニック
複数DataFrameでの条件抽出
# 別のDataFrameの条件を参照 df_targets = pd.DataFrame({ 'department': ['営業', 'IT'], 'min_salary': [450, 550] }) # 部署ごとの最低給与条件を満たす社員を抽出 result_list = [] for _, row in df_targets.iterrows(): dept_result = df[ (df['department'] == row['department']) & (df['salary'] >= row['min_salary']) ] result_list.append(dept_result) final_result = pd.concat(result_list, ignore_index=True)
日付・時間での複数条件
# 日付データのサンプル df_dates = pd.DataFrame({ 'name': ['田中', '佐藤', '鈴木'], 'join_date': pd.to_datetime(['2020-01-15', '2019-06-20', '2021-03-10']), 'salary': [400, 500, 450] }) # 特定期間内の入社で給与条件を満たす社員 start_date = pd.to_datetime('2020-01-01') end_date = pd.to_datetime('2021-12-31') result = df_dates[ (df_dates['join_date'] >= start_date) & (df_dates['join_date'] <= end_date) & (df_dates['salary'] >= 450) ]
実践演習:売上データ分析例
実際のビジネスシーンを想定した複数条件抽出の例を紹介します。
# 売上データのサンプル sales_df = pd.DataFrame({ 'date': pd.date_range('2023-01-01', periods=100), 'product': ['A', 'B', 'C'] * 33 + ['A'], 'sales_amount': np.random.randint(100, 1000, 100), 'region': ['東京', '大阪', '名古屋'] * 33 + ['東京'], 'salesperson': ['田中', '佐藤', '鈴木', '高橋'] * 25 }) # 複数条件での分析例 # 1. 高売上の東京エリア商品Aの売上データ high_sales_tokyo_a = sales_df[ (sales_df['sales_amount'] >= 500) & (sales_df['region'] == '東京') & (sales_df['product'] == 'A') ] # 2. 特定期間の特定営業担当の売上 target_period = sales_df['date'].between('2023-02-01', '2023-02-28') target_salesperson = sales_df['salesperson'].isin(['田中', '佐藤']) feb_sales = sales_df[target_period & target_salesperson] # 3. queryを使った複雑な分析 top_performers = sales_df.query( 'sales_amount >= 700 & region in ["東京", "大阪"] & product != "C"' )
よくある質問(FAQ)
Q: 複数条件で「and」「or」を使うとエラーが出るのはなぜですか?
A: pandasではand
やor
ではなく、&
や|
を使用する必要があります。また、各条件は必ず括弧で囲んでください。これはpandasがSeriesオブジェクトを扱うためです。
Q: 条件が多すぎて読みにくくなってしまいます。
A: 以下の方法で可読性を改善できます:
- 条件を変数に分けて記述
- queryメソッドを使用
- 改行を使って見やすく整理
- 関数化して再利用可能にする
Q: 大きなデータで複数条件の処理が遅いです。
A: パフォーマンス改善方法:
- データ型を最適化(category型、適切な数値型)
- 条件を変数に格納してから一度に評価
- queryメソッドの活用
- 不要な列を事前に削除
Q: NaN値がある列で条件抽出すると結果がおかしくなります。
A: NaN値は条件比較で常にFalseになります。事前にdropna()
で除外するか、pd.isna()
で明示的にNaN値の処理を指定してください。
まとめ:効率的な複数条件抽出をマスターしよう
pandasでの複数条件抽出について、基本から応用まで詳しく解説しました。
🎯 重要ポイントのまとめ:
- 基本構文:各条件を括弧で囲み、
&
(AND)、|
(OR)を使用 - 方法の選択:可読性重視なら
query
、パフォーマンス重視ならloc
- エラー対策:
and
/or
ではなく&
/|
、括弧必須 - パフォーマンス:データ型最適化、条件の変数化
- 実践応用:ビジネスデータ分析での活用方法
💡 次のステップ:
- 基本操作の習得:この記事のコードを実際に動かしてみる
- 応用練習:自分のデータで複数条件抽出を試す
- パフォーマンス最適化:大きなデータセットでの最適化に挑戦
- 関連技術の学習:groupbyやmergeと組み合わせた高度な分析
複数条件抽出は pandas の基本中の基本です。この記事の内容をマスターすれば、データ分析の効率が大幅に向上するはずです。ぜひ実際のプロジェクトで活用してみてください。
【関連記事】
Pandasのaggによる集計テクニック: 基本的な使い方、applyとの違い、条件付きカウント (count ifのような使い方)、最初の値の取得 (first value)など