pandas str.contains()の使い方|文字列を含む行を抽出・na=Falseも解説

pandas str.contains()の使い方

CSVを読み込んだあとに、次のように思うことはありませんか。

  • 商品名に「Pro」を含む行だけ見たい
  • 住所に「東京」を含むデータだけ抽出したい
  • カテゴリ名に特定の文字が入っている行だけ確認したい
  • 欠損値が混じっていて、文字列検索がうまくいかない

このように、完全一致ではなく「文字列の一部を含む行」を抽出したいときに使うのが、pandasの str.contains() です。

pandasで「contains」のように文字列を含む行を探したい場合は、str.contains() を使います。

結論から言うと、基本形は次のように書きます。

df[df["列名"].str.contains("探したい文字", na=False)]

na=False を付けると、欠損値がある行を False として扱えます。
そのため、欠損値が混じる列でも、初心者が安全に抽出しやすくなります。

この記事では、pandasの str.contains() を使って文字列を含む行を抽出する方法を、Google Colabで試しやすいサンプルで解説します。
あわせて、isin()query() との違い、na=False の意味、よくあるミスも整理します。

この記事でわかること

この記事では、次の内容を学べます。

  • str.contains() で文字列を含む行を抽出する方法
  • 完全一致と部分一致の違い
  • na=False を付ける理由
  • 特定の文字を含まない行を抽出する方法
  • 大文字・小文字を無視して検索する方法
  • regex=False を使って記号をそのまま検索する方法
  • isin()query()replace() との使い分け
  • 抽出後に head()value_counts() で確認する流れ

Pandas DataFrame入門シリーズの中での位置づけ

str.contains() は、DataFrameを読み込んだあとに、必要な行を探す・抽出するための操作です。

データ分析の流れで見ると、次のような位置づけになります。

  1. CSVを読み込む
  2. head()info() で中身を確認する
  3. str.contains() で文字列を含む行を抽出する
  4. 必要に応じて replace()fillna() で前処理する
  5. value_counts()groupby() で集計する

つまり、str.contains() は「確認したあと、必要なデータだけ取り出す」ための実用的な操作です。

str.contains()は文字列を含む行を抽出したいときに使う

str.contains() は、Seriesの各要素に対して「指定した文字列を含むかどうか」を調べます。

基本形は次のとおりです。

df[df["列名"].str.contains("探したい文字", na=False)]

ポイントは、df.str.contains() ではなく、文字列が入っている列を指定してから使うことです。

df["商品名"].str.contains("Pro", na=False)

この結果は、各行が条件に合うかどうかを表す True / False のデータになります。
それを df[...] の中に入れることで、条件に合う行だけを取り出せます。

最初は、次の3つをセットで覚えると分かりやすいです。

目的 書き方
文字を含む行を抽出する df[df["列名"].str.contains("文字", na=False)]
文字を含まない行を抽出する df[~df["列名"].str.contains("文字", na=False)]
大文字・小文字を無視する df[df["列名"].str.contains("文字", case=False, na=False)]

サンプルデータを作成する

まずは、商品名・住所・カテゴリ・メモを含む小さなDataFrameを作ります。
実務ではCSVから読み込むことが多いですが、ここではGoogle Colabでそのまま試せるように、サンプルデータを直接作成します。


import pandas as pd
import numpy as np

df = pd.DataFrame({
    "商品名": [
        "Basic Pen",
        "Pro Notebook",
        "Pro Mouse",
        "Mini Stand",
        "Desk Pro Max",
        "Standard Keyboard",
        "ProCase",
        "USB-C Cable"
    ],
    "住所": [
        "東京都新宿区",
        "大阪府大阪市",
        "東京都渋谷区",
        "神奈川県横浜市",
        "東京近郊",
        "北海道札幌市",
        np.nan,
        "京都府京都市"
    ],
    "カテゴリ": [
        "文房具",
        "PC周辺機器",
        np.nan,
        "家具",
        "PC周辺機器",
        "PC周辺機器",
        "アクセサリ",
        "ケーブル"
    ],
    "価格": [120, 98000, 4500, 3200, 128000, 8500, 2400, 1600],
    "メモ": [
        "初回入荷",
        "Pro対象",
        "在庫確認",
        "セール対象",
        "PRO表記あり",
        np.nan,
        "proの小文字あり",
        "記号A+Bを含む"
    ]
})

df
商品名 住所 カテゴリ 価格 メモ
0 Basic Pen 東京都新宿区 文房具 120 初回入荷
1 Pro Notebook 大阪府大阪市 PC周辺機器 98000 Pro対象
2 Pro Mouse 東京都渋谷区 NaN 4500 在庫確認
3 Mini Stand 神奈川県横浜市 家具 3200 セール対象
4 Desk Pro Max 東京近郊 PC周辺機器 128000 PRO表記あり
5 Standard Keyboard 北海道札幌市 PC周辺機器 8500 NaN
6 ProCase NaN アクセサリ 2400 proの小文字あり
7 USB-C Cable 京都府京都市 ケーブル 1600 記号A+Bを含む

このDataFrameには、あえて次のようなデータを入れています。

列名 目的
商品名 「Pro」を含む商品を抽出する例に使う
住所 「東京」を含む住所を抽出する例に使う
カテゴリ 欠損値がある場合の na=False を説明するために使う
メモ 大文字小文字や記号検索の注意点を説明するために使う

このように、str.contains() は商品名、住所、カテゴリ、メモ欄など、文字列が入っている列でよく使います。

商品名に「Pro」を含む行を抽出する

まずは、商品名に Pro を含む行だけを抽出してみます。


df[df["商品名"].str.contains("Pro", na=False)]
商品名 住所 カテゴリ 価格 メモ
1 Pro Notebook 大阪府大阪市 PC周辺機器 98000 Pro対象
2 Pro Mouse 東京都渋谷区 NaN 4500 在庫確認
4 Desk Pro Max 東京近郊 PC周辺機器 128000 PRO表記あり
6 ProCase NaN アクセサリ 2400 proの小文字あり

上のコードでは、次の流れで処理しています。

  1. df["商品名"] で商品名の列を取り出す
  2. .str.contains("Pro", na=False) で「Proを含むか」を調べる
  3. df[...]True になった行だけを抽出する

処理前と処理後のイメージは次のとおりです。

状態 内容
処理前 すべての商品が表示されている
条件 商品名に Pro を含むか調べる
処理後 Pro NotebookPro MouseDesk Pro MaxProCase などが残る

ここで重要なのは、str.contains()完全一致ではなく部分一致だという点です。
そのため、ProCaseDesk Pro Max のように、文字列の一部に Pro が入っていれば抽出対象になります。

完全一致・部分一致・候補リスト・置換の違い

初心者が迷いやすいのは、==isin()str.contains()replace() の使い分けです。

最初に判断基準を整理しておきます。

やりたいこと 使う方法
ある値と完全に一致する行を抽出したい == 商品名が Pro Mouse の行
複数の候補のどれかに完全一致する行を抽出したい isin() カテゴリが 家具 または ケーブル の行
文字列の一部を含む行を抽出したい str.contains() 商品名に Pro を含む行
条件式を文字列として書きたい query() 価格 >= 5000 のような条件を書く
値そのものを置き換えたい replace() / str.replace() PC周辺機器パソコン関連 に直す

query() は条件式をすっきり書ける便利な方法ですが、文字列の部分一致を学び始めた段階では、まず df[df["列名"].str.contains("文字", na=False)] の形で理解するのがおすすめです。

str.contains() は、値を変更する処理ではありません
条件に合う行を「取り出す」ための処理です。


# 完全一致:商品名が「Pro Mouse」と完全に一致する行
df[df["商品名"] == "Pro Mouse"]
商品名 住所 カテゴリ 価格 メモ
2 Pro Mouse 東京都渋谷区 NaN 4500 在庫確認

# 候補リスト:カテゴリが「家具」または「ケーブル」の行
df[df["カテゴリ"].isin(["家具", "ケーブル"])]
商品名 住所 カテゴリ 価格 メモ
3 Mini Stand 神奈川県横浜市 家具 3200 セール対象
7 USB-C Cable 京都府京都市 ケーブル 1600 記号A+Bを含む

# 部分一致:商品名に「Pro」を含む行
df[df["商品名"].str.contains("Pro", na=False)]
商品名 住所 カテゴリ 価格 メモ
1 Pro Notebook 大阪府大阪市 PC周辺機器 98000 Pro対象
2 Pro Mouse 東京都渋谷区 NaN 4500 在庫確認
4 Desk Pro Max 東京近郊 PC周辺機器 128000 PRO表記あり
6 ProCase NaN アクセサリ 2400 proの小文字あり

この3つは似ていますが、役割が違います。

  • == は1つの値との完全一致
  • isin() は複数候補との完全一致
  • str.contains() は文字列の一部一致

「Proを含む商品名」のように、文字列の一部を探したい場合は、str.contains() が自然です。

住所に「東京」を含む行を抽出する

次に、住所列に 東京 を含む行だけを抽出します。

住所や店舗名、商品名、カテゴリ名などは、完全一致よりも「一部に含まれるか」で探したい場面がよくあります。


df[df["住所"].str.contains("東京", na=False)]
商品名 住所 カテゴリ 価格 メモ
0 Basic Pen 東京都新宿区 文房具 120 初回入荷
2 Pro Mouse 東京都渋谷区 NaN 4500 在庫確認
4 Desk Pro Max 東京近郊 PC周辺機器 128000 PRO表記あり

この例では、東京都新宿区東京都渋谷区東京近郊 のように、住所の一部に 東京 を含む行が抽出されます。

処理前後のイメージは次のとおりです。

住所 東京を含むか 抽出結果
0 東京都新宿区 True 残る
1 大阪府大阪市 False 残らない
2 東京都渋谷区 True 残る
3 神奈川県横浜市 False 残らない
4 東京近郊 True 残る
6 欠損値 False扱い 残らない

na=False を付けているため、住所が欠損している行は False として扱われます。

na=Falseを付ける理由

str.contains() を使うときに、初心者がつまずきやすいのが na=False です。

検索対象の列に欠損値がある場合、str.contains() の判定結果にも欠損値が混じることがあります。
この判定結果をそのままDataFrameの抽出条件に使うと、列の型や欠損値の扱いによってはエラーになることがあります。


# na=False を付けない場合の判定結果
mask = df["カテゴリ"].str.contains("PC")
mask
カテゴリ
0 False
1 True
2 NaN
3 False
4 True
5 True
6 False
7 False

上の結果を見ると、カテゴリ が欠損している行では、判定結果にも欠損値が混じっています。

この状態でDataFrameの抽出条件に使うと、列の型や欠損値の扱いによってはエラーになることがあります。
そのため、初心者向けには na=False を付けておく書き方がおすすめです。


# na=False を付けると、欠損値は False として扱われる
df[df["カテゴリ"].str.contains("PC", na=False)]
商品名 住所 カテゴリ 価格 メモ
1 Pro Notebook 大阪府大阪市 PC周辺機器 98000 Pro対象
4 Desk Pro Max 東京近郊 PC周辺機器 128000 PRO表記あり
5 Standard Keyboard 北海道札幌市 PC周辺機器 8500 NaN

na=False の意味は、次のように考えると分かりやすいです。

書き方 欠損値がある行の扱い 初心者向けの使いやすさ
str.contains("PC") 欠損値が判定結果に残ることがある エラーや混乱につながりやすい
str.contains("PC", na=False) 欠損値を False として扱う 安全に抽出しやすい

「欠損値の行は、検索文字を含まないものとして扱いたい」場合は、na=False を付けるのが自然です。

特に、次のような実務データでは na=False を付けておくと安心です。

  • 商品名や住所に空欄がある
  • メモ欄に未入力の行がある
  • CSVを読み込んだ直後で、欠損値の有無をまだ確認できていない

特定の文字を含まない行を抽出する

str.contains() の前に ~ を付けると、条件を反転できます。

つまり、「Proを含む行」ではなく、Proを含まない行を抽出できます。


df[~df["商品名"].str.contains("Pro", na=False)]
商品名 住所 カテゴリ 価格 メモ
0 Basic Pen 東京都新宿区 文房具 120 初回入荷
3 Mini Stand 神奈川県横浜市 家具 3200 セール対象
5 Standard Keyboard 北海道札幌市 PC周辺機器 8500 NaN
7 USB-C Cable 京都府京都市 ケーブル 1600 記号A+Bを含む

~ は「ではない」という意味で使います。

~df["商品名"].str.contains("Pro", na=False)

この条件は、「商品名に Pro を含まない」という意味になります。

ただし、na=False を付け忘れると、欠損値が混じる列ではうまく反転できないことがあります。
~ と一緒に使う場合も、基本的には na=False を付けておくと安心です。

大文字・小文字を無視して検索する

英字を含むデータでは、ProPROpro のように表記が混じることがあります。

デフォルトでは、大文字と小文字は区別されます。


# デフォルトでは大文字・小文字を区別する
df[df["メモ"].str.contains("pro", na=False)]
商品名 住所 カテゴリ 価格 メモ
6 ProCase NaN アクセサリ 2400 proの小文字あり

上の例では、小文字の pro を含む行だけが抽出されます。

大文字・小文字を区別せずに検索したい場合は、case=False を使います。


# case=False で大文字・小文字を区別せずに検索
df[df["メモ"].str.contains("pro", case=False, na=False)]
商品名 住所 カテゴリ 価格 メモ
1 Pro Notebook 大阪府大阪市 PC周辺機器 98000 Pro対象
4 Desk Pro Max 東京近郊 PC周辺機器 128000 PRO表記あり
6 ProCase NaN アクセサリ 2400 proの小文字あり

case=False を使うと、ProPROpro のような表記ゆれをまとめて検索できます。

ただし、case=False は「抽出時に大文字小文字を無視する」だけです。
データ自体を書き換える処理ではありません。表記そのものをそろえたい場合は、replace() や文字列処理を使う流れになります。

記号をそのまま探したいときはregex=Falseを付ける

str.contains() は、デフォルトでは検索文字を正規表現として扱います。

正規表現とは、文字列のパターンを表す書き方です。便利ですが、初心者のうちは +.? などの記号を検索するときに、意図しない結果になることがあります。

たとえば、メモ欄から A+B という文字をそのまま探したい場合、+ が正規表現の特別な記号として解釈されることがあります。
記号を普通の文字として探したいときは、regex=False を付けると安全です。


# 「A+B」という文字をそのまま探したい場合
df[df["メモ"].str.contains("A+B", regex=False, na=False)]
商品名 住所 カテゴリ 価格 メモ
7 USB-C Cable 京都府京都市 ケーブル 1600 記号A+Bを含む

今回の記事では、正規表現の詳しい書き方には深入りしません。

初心者のうちは、次のように覚えておくと十分です。

場面 書き方
普通の文字を含むか調べる str.contains("東京", na=False)
+. などの記号をそのまま探す str.contains("A+B", regex=False, na=False)
正規表現を使って複数パターンを探す 慣れてから学べばよい

まずは、na=Falseregex=False の役割を分けて理解しましょう。

  • na=False:欠損値を False として扱う
  • regex=False:検索文字を正規表現ではなく、普通の文字として扱う

str.contains()を複数条件と組み合わせる方法

str.contains() は、ほかの条件と組み合わせることもできます。

たとえば、商品名に Pro を含み、価格が5000円以上の商品だけを抽出してみます。


df[
    df["商品名"].str.contains("Pro", na=False)
    & (df["価格"] >= 5000)
]
商品名 住所 カテゴリ 価格 メモ
1 Pro Notebook 大阪府大阪市 PC周辺機器 98000 Pro対象
4 Desk Pro Max 東京近郊 PC周辺機器 128000 PRO表記あり

ここでは、2つの条件を & でつないでいます。

  • 商品名に Pro を含む
  • 価格が5000円以上

複数条件の詳しい書き方や query() の使い方は条件抽出の記事で扱う内容なので、この記事では深追いしません。
str.contains() は、あくまで「文字列を含むかどうかの条件を作る」と理解しておくと整理しやすいです。

抽出後に確認・前処理・集計へつなげる

str.contains() で行を抽出したら、そこで終わりではありません。

抽出したデータを確認し、必要に応じて前処理や集計につなげます。
たとえば、Pro を含む商品だけを取り出したあと、カテゴリごとの件数を確認してみます。


pro_items = df[df["商品名"].str.contains("Pro", na=False)]

pro_items.head()
商品名 住所 カテゴリ 価格 メモ
1 Pro Notebook 大阪府大阪市 PC周辺機器 98000 Pro対象
2 Pro Mouse 東京都渋谷区 NaN 4500 在庫確認
4 Desk Pro Max 東京近郊 PC周辺機器 128000 PRO表記あり
6 ProCase NaN アクセサリ 2400 proの小文字あり

pro_items["カテゴリ"].value_counts(dropna=False)
count
PC周辺機器 2
NaN 1
アクセサリ 1

このように、str.contains() はデータ分析の流れの中で、次のように使えます。

流れ 使う操作の例
データを読み込む read_csv()
中身を確認する head()info()
必要な行を探す str.contains()
値の表記ゆれを直す replace()
欠損値を確認・処理する isnull()fillna()
件数を見る value_counts()
グループごとに集計する groupby()

str.contains() は、確認と前処理、集計をつなぐための「対象データを探す操作」と考えると分かりやすいです。

よくあるミスと対処法

str.contains() では、次のようなミスが起きやすいです。

よくあるミス 原因 対処
df.str.contains() と書いてしまう DataFrame全体には直接使えない df["列名"].str.contains() と書く
欠損値が混じって抽出できない 判定結果に欠損値が混じる na=False を付ける
完全一致のつもりで使ってしまう str.contains() は部分一致 完全一致なら ==isin() を使う
記号検索で意図しない結果になる デフォルトで正規表現扱い regex=False を付ける
抽出しただけなのに元データが変わったと思う 抽出は行を取り出す処理 値の変更は replace() などを使う
query() と混同する query() は条件式の書き方、str.contains() は文字列判定 文字列の部分一致はまず str.contains() で考える

特に、最初は次の2点を押さえるだけでも十分です。

  • 欠損値がありそうな列では na=False を付ける
  • 完全一致ではなく、文字列の一部を探すときに str.contains() を使う

この記事で深入りしない発展内容

str.contains() は正規表現と組み合わせると、より複雑な文字列検索もできます。

ただし、この記事では初心者が最初に使いやすいように、1列から特定の文字を含む行を抽出する基本に絞っています。

次の内容は便利ですが、最初から深く覚えなくても大丈夫です。

  • 複雑な正規表現パターン
  • 複数列をまたぐ文字列検索
  • str.extract()str.match() の詳しい使い方
  • 大量データでの高速化
  • 自然言語処理やテキストマイニング

まずは、str.contains("文字", na=False) の基本形を使えるようになることを優先しましょう。

まとめ

この記事では、pandasの str.contains() を使って、文字列を含む行を抽出する方法を解説しました。

大切なポイントは次のとおりです。

  • 文字列の一部を含む行を抽出したいときは str.contains() を使う
  • 基本形は df[df["列名"].str.contains("文字", na=False)]
  • 完全一致なら ==isin()、部分一致なら str.contains() と使い分ける
  • 欠損値が混じる列では na=False を付けると安全
  • 含まない行を抽出したいときは ~ を使う
  • 大文字・小文字を無視したい場合は case=False を使う
  • 記号をそのまま検索したい場合は regex=False を使う
  • 抽出後は head()value_counts() で確認すると次の分析につなげやすい

str.contains() は、商品名・住所・カテゴリ・メモ欄など、文字列データを扱うときによく使います。
まずは str.contains("文字", na=False) の基本形を覚え、必要に応じて ~case=Falseregex=False を加えていきましょう。

次に読みたい関連記事

この記事の内容は、次の記事とあわせて読むと理解しやすくなります。

まずDataFrameの基本やCSV読み込みを確認し、そのあと条件抽出・isin・replace・value_countsへ進むと、文字列データの確認から前処理までの流れがつながりやすくなります。

▲ ページトップへ戻る

str.contains()とisin()の違いは何ですか?

str.contains() は、文字列の一部を含むかどうかを調べる部分一致の方法です。
一方、isin() は、指定した候補リストのどれかに完全一致するかを調べる方法です。
商品名に Pro を含む行を探すなら str.contains()、カテゴリが 家具 または ケーブル のように決まった値に一致する行を探すなら isin() が向いています。

na=Falseはいつ付ければよいですか?

検索対象の列に欠損値がある可能性があるときは、基本的に付けておくと安心です。
na=False は、「欠損値の行は検索文字を含まないものとして扱う」という意味です。
初心者のうちは、まず str.contains("文字", na=False) の形を基本にすると安全です。

大文字と小文字を区別せずに検索できますか?

できます。
case=False を使います。
df[df["メモ"].str.contains("pro", case=False, na=False)]
このように書くと、ProPROpro などをまとめて検索できます。

特定の文字を含まない行を抽出できますか?

できます。
~ を使って条件を反転します。
df[~df["商品名"].str.contains("Pro", na=False)]
このコードは、商品名に Pro を含まない行を抽出します。

str.contains()で正規表現を使わないようにできますか?

できます。
regex=False を使います。
df[df["メモ"].str.contains("A+B", regex=False, na=False)]
+ や . などの記号を、そのままの文字として検索したい場合に役立ちます。

str.contains()とquery()はどちらを使えばよいですか?

初心者のうちは、まず df[df["列名"].str.contains("文字", na=False)] の形をおすすめします。
query() は条件を文字列として書ける便利な方法ですが、文字列メソッドを組み合わせると書き方が少し難しくなります。
まずは通常の条件抽出に慣れてから、必要に応じて query() を使うと理解しやすいです。

コメント

タイトルとURLをコピーしました