【Python】Pandas DataFrameで条件に一致するデータを抽出(フィルタリング)する方法

大量のデータを保持するPandasのDataFrameから、特定の条件を満たす行だけを抽出する操作は、データ分析において最も重要な工程の一つです。Pandasでは「ブールインデックス参照」という仕組みを利用して、SQLのWHERE句やExcelのフィルタ機能のようなデータ抽出を直感的に記述できます。

本記事では、比較演算子を用いた数値フィルタリングから、正規表現を利用した文字列抽出まで、実戦的なフィルタリング手法について解説します。

目次

ブールインデックス参照によるデータの抽出

ブールインデックス参照とは、各行に対して「条件を満たすか(True)」または「満たさないか(False)」を判定した真偽値の配列(Series)をDataFrameに渡すことで、Trueの行のみを取り出す手法です。

比較演算子を用いた基本的なフィルタリング

数値データの大小比較や一致判定を行う例を紹介します。ここでは図書館の蔵書カタログを想定したシナリオを使用します。

import pandas as pd

def basic_filtering_demo():
    """
    比較演算子を用いた基本的なフィルタリング手法を実演する関数
    """
    # 蔵書データの作成
    book_data = {
        "Title": ["Python Basics", "Mastering Java", "SQL Guide", "Data Science 101", "Advanced C++"],
        "Category": ["Programming", "Programming", "Database", "Analysis", "Programming"],
        "Price": [2800, 3500, 1500, 4200, 3800],
        "Stock": [15, 4, 20, 7, 0]
    }
    df = pd.DataFrame(book_data)

    print("--- 元の蔵書リスト ---")
    print(df)
    print("\n")

    # 1. 完全一致による抽出 (Categoryが 'Programming' の本)
    programming_books = df[df["Category"] == "Programming"]
    print("--- プログラミング関連書籍 ---")
    print(programming_books)

    # 2. 大小比較による抽出 (Priceが 3000円より高い本)
    expensive_books = df[df["Price"] > 3000]
    print("\n--- 3000円超の書籍 ---")
    print(expensive_books)

    # 3. インデックスの偶数行のみを抽出
    # インデックスに対して演算を行い、True/Falseのシーケンスを生成
    even_rows = df[df.index % 2 == 0]
    print("\n--- インデックスが偶数行のデータ ---")
    print(even_rows)

if __name__ == "__main__":
    basic_filtering_demo()

複数条件(AND / OR)を組み合わせた抽出

複数の条件を組み合わせてフィルタリングを行う場合は、各条件を丸括弧 () で囲み、ビット演算子(&|)を使用します。

  • AND条件 (&): すべての条件を満たす行を抽出
  • OR条件 (|): いずれかの条件を満たす行を抽出
import pandas as pd

def multiple_conditions_demo():
    """
    複数の条件を組み合わせたフィルタリングを実演する関数
    """
    data = {
        "Model": ["Standard-A", "Standard-B", "Pro-X", "Pro-Y", "Ultra-Z"],
        "Sales": [120, 85, 200, 150, 300],
        "Price": [15000, 18000, 45000, 48000, 95000]
    }
    df = pd.DataFrame(data)

    # 例: 価格が20000円以上 かつ 売上が200以上のモデルを抽出
    # 各条件を () で囲むことが必須です
    condition_and = (df["Price"] >= 20000) & (df["Sales"] >= 200)
    filtered_df = df[condition_and]

    print("--- 利益率が高いモデル (Price>=20000 & Sales>=200) ---")
    print(filtered_df)

if __name__ == "__main__":
    multiple_conditions_demo()

文字列操作と正規表現を用いた高度なフィルタリング

文字列型の列に対しては、.str アクセサを通じて強力な検索機能を利用できます。特に contains メソッドは、特定のパターンを含む文字列の抽出に非常に有用です。

import pandas as pd

def string_regex_filtering():
    """
    文字列操作と正規表現を用いたフィルタリングを実演する関数
    """
    # 顧客アンケートデータの作成
    feedback_data = {
        "Customer": ["User_01", "User_02", "User_03", "User_04", "User_05"],
        "Comment": [
            "The design is excellent.",
            "Performance is slow.",
            "Great performance and support.",
            "Not good value for money.",
            "Excellent performance overall."
        ]
    }
    df = pd.DataFrame(feedback_data)

    # 1. 特定のキーワードを含む行を抽出
    # "performance" という単語を含むコメントを抽出 (大文字小文字を区別しない設定)
    performance_feedback = df[df["Comment"].str.contains("performance", case=False)]
    
    print("--- パフォーマンスに関するフィードバック ---")
    print(performance_feedback)

    # 2. 正規表現を用いた複雑な抽出
    # "Excellent" または "Great" で始まるコメントを抽出
    # ^ は行頭、 | はORを意味する正規表現
    regex_condition = df["Comment"].str.contains(r"^(Excellent|Great)", regex=True)
    positive_feedback = df[regex_condition]

    print("\n--- 高評価のフィードバック (正規表現抽出) ---")
    print(positive_feedback)

if __name__ == "__main__":
    string_regex_filtering()

実行結果の解説

  1. 比較演算: df[df["Price"] > 3000] のように記述すると、内部的に各行の判定結果が真偽値 Series として生成され、条件に合致する行のみが再構築されます。
  2. 複数条件: & 演算子を使用する際、Pandasでは and キーワードは使用できません。必ずビット演算子 & を使い、優先順位を明確にするために条件式を括弧で囲んでください。
  3. str.contains: 部分一致検索を簡単に行えます。regex=True(デフォルト)に設定することで、強力な正規表現パターンマッチングが可能になります。

これらのフィルタリング手法を習得することで、膨大なデータの中から必要な情報を瞬時に特定し、分析の精度を高めることができます。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

私が勉強したこと、実践したこと、してることを書いているブログです。
主に資産運用について書いていたのですが、
最近はプログラミングに興味があるので、今はそればっかりです。

目次