データ分析において、特定の条件に合致するデータを大量のデータの中から探し出す作業は日常茶飯事です。あなたは、こんなデータ検索で困った経験はありませんか?
- 「東京」と「大阪」と「福岡」からの注文だけ見たい
- 「商品番号 101番」「205番」「330番」のデータだけ必要だ
- 「Aさん」「Bさん」「Cさん」のデータだけをまとめて見たい
一つ一つ条件を指定して検索することもできますが、対象の値が増えるとコードが長くなり、書くのも読むのも大変になります。
Pandasを使ったデータ分析では、様々なデータ検索方法がありますが、「このリストに入っているどれかの値」という条件で、データを簡単に探し出すことができます。
この記事では、このisin
メソッドがどんな時に便利で、どうやって使うのかを、分かりやすく解説していきます。これを読めば、今まで手間に感じていた複数の条件でのデータ検索が、リスト一つでサクッとできるようになります!
▶️ isinの公式ドキュメントも参考にしてください:
pandas DataFrame isin Documentation
データ検索の基礎とisinの役割
まずはデータ検索の基本から見ていきましょう。PandasのDataFrameから特定のデータを探すには、様々な方法があります。例えば、特定の列の値が「〇〇」である行を抽出したい場合は、以下のように==演算子を使うのが一般的です。
まずはサンプルデータを作成しましょう。
import pandas as pd
df = pd.DataFrame({
"名前": ["太郎", "花子", "次郎", "美香", "健一", "恵子", "翔", "茜", "隆", "葵"],
"年齢": [23, 29, 35, 42, 18, 33, 27, 24, 31, 30],
"職業": ["エンジニア", "デザイナー", "教師", "医師", "学生", "看護師", "プログラマー", "販売員", "弁護士", "研究者"],
"年収(円)": [4500000, 5500000, 4900000, 7300000, 0, 4000000, 6000000, 3200000, 8000000, 5800000],
"居住地": ["東京", "大阪", "名古屋", "札幌", "福岡", "東京", "神戸", "仙台", "横浜", "千葉"],
"勤続年数": [2, 4, 10, 15, 1, 5, 3, 1, 12, 8]
})
df
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
0 | 太郎 | 23 | エンジニア | 4500000 | 東京 | 2 |
1 | 花子 | 29 | デザイナー | 5500000 | 大阪 | 4 |
2 | 次郎 | 35 | 教師 | 4900000 | 名古屋 | 10 |
3 | 美香 | 42 | 医師 | 7300000 | 札幌 | 15 |
4 | 健一 | 18 | 学生 | 0 | 福岡 | 1 |
5 | 恵子 | 33 | 看護師 | 4000000 | 東京 | 5 |
6 | 翔 | 27 | プログラマー | 6000000 | 神戸 | 3 |
7 | 茜 | 24 | 販売員 | 3200000 | 仙台 | 1 |
8 | 隆 | 31 | 弁護士 | 8000000 | 横浜 | 12 |
9 | 葵 | 30 | 研究者 | 5800000 | 千葉 | 8 |
例として、年齢が35歳の行を抽出しましょう
df[df["年齢"] == 35]
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
2 | 次郎 | 35 | 教師 | 4900000 | 名古屋 | 10 |
これは非常にシンプルで分かりやすい方法です。しかし、もし「年齢が23歳 または 29歳 または 35歳」のように、複数の特定のいずれかの値に合致する行を抽出したい場合はどうでしょうか?
==演算子と|(or)を組み合わせて書くこともできますが、条件が増えるとコードが長くなり、少し読みにくくなってしまいます。
df[(df["年齢"] == 23) | (df["年齢"] == 29) | (df["年齢"] == 35)]
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
0 | 太郎 | 23 | エンジニア | 4500000 | 東京 | 2 |
1 | 花子 | 29 | デザイナー | 5500000 | 大阪 | 4 |
2 | 次郎 | 35 | 教師 | 4900000 | 名古屋 | 10 |
このような「複数の特定の値」に合致するデータを検索する際に、isinメソッドが役立ちます
isinメソッドの基本的な使い方:リストを活用
isinメソッドは、DataFrameやSeriesの要素が、指定したリストに含まれているかどうかを確認するためのメソッドです。結果はTrue/Falseの真偽値で返されます。
基本的な使い方は非常にシンプルです。検索したい値をリストとしてisin()に渡すだけです。
さきほどのサンプルデータを活用してみましょう
df
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
0 | 太郎 | 23 | エンジニア | 4500000 | 東京 | 2 |
1 | 花子 | 29 | デザイナー | 5500000 | 大阪 | 4 |
2 | 次郎 | 35 | 教師 | 4900000 | 名古屋 | 10 |
3 | 美香 | 42 | 医師 | 7300000 | 札幌 | 15 |
4 | 健一 | 18 | 学生 | 0 | 福岡 | 1 |
5 | 恵子 | 33 | 看護師 | 4000000 | 東京 | 5 |
6 | 翔 | 27 | プログラマー | 6000000 | 神戸 | 3 |
7 | 茜 | 24 | 販売員 | 3200000 | 仙台 | 1 |
8 | 隆 | 31 | 弁護士 | 8000000 | 横浜 | 12 |
9 | 葵 | 30 | 研究者 | 5800000 | 千葉 | 8 |
isinを使った文字列の抽出例
「居住地」列に「東京」または「横浜」が含まれている行を検索してみましょう。検索したい値(”東京”, “横浜”)をリストにしてisin()に渡します。
isin_tokyo_yokohama=df["居住地"].isin(["東京", "横浜"])
isin_tokyo_yokohama
居住地 | |
---|---|
0 | True |
1 | False |
2 | False |
3 | False |
4 | False |
5 | True |
6 | False |
7 | False |
8 | True |
9 | False |
filtered_df = df[isin_tokyo_yokohama]
filtered_df
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
0 | 太郎 | 23 | エンジニア | 4500000 | 東京 | 2 |
5 | 恵子 | 33 | 看護師 | 4000000 | 東京 | 5 |
8 | 隆 | 31 | 弁護士 | 8000000 | 横浜 | 12 |
ご覧のように、isin([“東京”, “横浜”])と書くだけで、複数の条件を簡単に指定できます。これは、(df[“居住地”] == “東京”) | (df[“居住地”] == “横浜”)と書くよりも、コードが短く、目的が明確です。
isinを使った数値データの抽出例
数値の検索でも同様に使えます。「勤続年数」が1年または5年の行を検索してみましょう。
isin_1_or_5_years = df["勤続年数"].isin([1, 5])
isin_1_or_5_years
勤続年数 | |
---|---|
0 | False |
1 | False |
2 | False |
3 | False |
4 | True |
5 | True |
6 | False |
7 | True |
8 | False |
9 | False |
Trueとなった行(つまり、勤続年数が1年または5年の行)を抽出
filtered_df_years = df[isin_1_or_5_years]
filtered_df_years
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
4 | 健一 | 18 | 学生 | 0 | 福岡 | 1 |
5 | 恵子 | 33 | 看護師 | 4000000 | 東京 | 5 |
7 | 茜 | 24 | 販売員 | 3200000 | 仙台 | 1 |
こちらもリストに含めるだけで、複数の数値を簡単に検索できます。
なぜisinではリスト形式を使うのか?
ここで少し補足します。isinはたとえ単一の値だけを検索したい場合でも、引数としてリスト形式を要求します。 リストは、複数の要素を順序付けして格納できるデータ構造です。Pythonでは、角かっこ [] を使ってリストを作成し、要素をカンマ , で区切ります。単一の要素の場合はカンマで区切る必要はありません。
正しい使い方 * df[“居住地”].isin([“東京”])
間違った使い方:リストで渡していないのでエラーになります。
- df[“居住地”].isin(“東京”)
isinメソッドが複数の値を一度に効率的に検索できるように設計されています。「isinは検索したい値が一つだけでも、リストとして渡すのが正しい」と覚えておきましょう。
isinメソッドのメリット・デメリットと比較
ここで、isinメソッドを使うメリットと、他の方法(==演算子)を使う場合の使い分けについて整理します。
isinのメリット
複数の値の検索が容易: 検索したい値をリストで指定するだけで、複数の条件をシンプルに記述できます。 コードの簡潔性: 複数の==条件を|で繋ぐ場合に比べて、コードが短く読みやすくなります。 効率性: Pandasの内部で効率的に処理されるため、特に大規模なデータセットで複数の値を検索する場合にパフォーマンスが良いことがあります。 isinを使う必要がない場合(==演算子の方が適している場合)
単一の値の検索: 検索したい値が一つだけであれば、==演算子を使う方が直感的でコードもわずかに短くなります。
# 単一の値の検索:==演算子の方がシンプル
df["居住地"] == "東京"
居住地 | |
---|---|
0 | True |
1 | False |
2 | False |
3 | False |
4 | False |
5 | True |
6 | False |
7 | False |
8 | False |
9 | False |
# 単一の値の検索:isinも使えるが、リストにする必要がある
df["居住地"].isin(["東京"])
居住地 | |
---|---|
0 | True |
1 | False |
2 | False |
3 | False |
4 | False |
5 | True |
6 | False |
7 | False |
8 | False |
9 | False |
単一の値の検索であればどちらを使っても結果は同じですが、コードの意図を明確にするためには、単一値には==、複数値にはisinという使い分けが良いでしょう。
ISINメソッドの実践的な応用例
これまでのお話は、単一の列に対する isin の使用例が中心でしたが、複数の列を組み合わせた検索など、より実践的な応用例を加えることで、読者は isin をさらに幅広いシナリオで活用できるようになります。
複数の列で isin を組み合わせる方法
特定の条件を満たす行を、複数の列の値に基づいてフィルタリングするケースを想定します。例:居住地が「東京」または「大阪」かつ、職業が「エンジニア」または「デザイナー」の行を抽出
filtered_df_multiple_cols = df[
df["居住地"].isin(["東京", "大阪"]) & df["職業"].isin(["エンジニア", "デザイナー"])
]
filtered_df_multiple_cols
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
0 | 太郎 | 23 | エンジニア | 4500000 | 東京 | 2 |
1 | 花子 | 29 | デザイナー | 5500000 | 大阪 | 4 |
「居住地が『東京』または『大阪』」という条件と、「職業が『エンジニア』または『デザイナー』」という条件を組み合わせたい場合は、それぞれの条件をisinで指定し、&演算子(論理AND)で結合します。このように、isinは他の条件と組み合わせて使うことも可能です。
isinと他の条件式を組み合わせる方法
isin と > や < といった比較演算子を組み合わせる例も考えられます。例:居住地が「東京」または「大阪」で、年収が500万円以上の行を抽出
filtered_df_isin_comparison = df[
df["居住地"].isin(["東京", "大阪"]) & (df["年収(円)"] >= 5000000)
]
filtered_df_isin_comparison
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
1 | 花子 | 29 | デザイナー | 5500000 | 大阪 | 4 |
「居住地が『東京』または『大阪』」という条件に加えて、「年収が500万円以上」という条件を追加したい場合、isinで居住地の条件を指定し、年収の条件は >= 演算子で指定します。複数の異なる種類の条件を組み合わせる際にも、isin は他のフィルタリング方法と自然に組み合わせることができます。
isinを使ったデータの否定検索
isin は指定したリストに含まれる要素を持つ行を抽出しますが、逆にリストに含まれない要素を持つ行を抽出したい場合もあります。このような否定条件でフィルタリングしたい場合は、isin() の結果に ~ (チルダ) 演算子を前置します。~ は真偽値を反転させる役割があります。
例として、「居住地が『東京』でも『大阪』でもない行」を抽出してみましょう。
isin_tokyo_osaka = df["居住地"].isin(["東京", "大阪"])
isin_tokyo_osaka
居住地 | |
---|---|
0 | True |
1 | True |
2 | False |
3 | False |
4 | False |
5 | True |
6 | False |
7 | False |
8 | False |
9 | False |
上記の条件を反転させる(~isinを使用)
not_in_tokyo_osaka = ~isin_tokyo_osaka
not_in_tokyo_osaka
居住地 | |
---|---|
0 | False |
1 | False |
2 | True |
3 | True |
4 | True |
5 | False |
6 | True |
7 | True |
8 | True |
9 | True |
反転した条件でフィルタリング
filtered_df_not_in = df[not_in_tokyo_osaka]
filtered_df_not_in
名前 | 年齢 | 職業 | 年収(円) | 居住地 | 勤続年数 | |
---|---|---|---|---|---|---|
2 | 次郎 | 35 | 教師 | 4900000 | 名古屋 | 10 |
3 | 美香 | 42 | 医師 | 7300000 | 札幌 | 15 |
4 | 健一 | 18 | 学生 | 0 | 福岡 | 1 |
6 | 翔 | 27 | プログラマー | 6000000 | 神戸 | 3 |
7 | 茜 | 24 | 販売員 | 3200000 | 仙台 | 1 |
8 | 隆 | 31 | 弁護士 | 8000000 | 横浜 | 12 |
9 | 葵 | 30 | 研究者 | 5800000 | 千葉 | 8 |
大規模データにおけるisinのパフォーマンス(上級者向け)
大規模なデータセットに対して複数の値を検索する場合、isin メソッドの方が == 演算子を | で多数繋ぐよりも効率的に処理される傾向があります。これは、isin が内部で最適化された方法で複数の値を検索するためです。特に検索したい値が多いほど、isin のパフォーマンス上のメリットが顕著になります。ただし、パフォーマンスはデータセットのサイズや検索する値の数など、様々な要因に影響されるため、状況に応じて最も効率的な方法を選択することが重要です。 ここでは、簡単なベンチマークを行ってパフォーマンスの違いを見てみましょう。
import time
import numpy as np
import pandas as pd
# 大規模なサンプルデータを作成
large_df = pd.DataFrame({
"値": np.random.randint(0, 1000, 1000000) # 値の範囲を広げ、より多くのユニークな値を生成
})
# 検索する値のリスト(数を増やしてみる)
search_values = list(range(10, 100)) # 検索する値の数を増やす (例: 90個)
print(f"データサイズ: {len(large_df)} 行")
print(f"検索する値の数: {len(search_values)} 個")
# isin を使用した場合の処理時間
print("\nisin を使用した検索...")
start_time = time.time()
large_df[large_df["値"].isin(search_values)]
isin_time = time.time() - start_time
print(f"処理時間: {isin_time:.6f} 秒")
# == 演算子と | を使用した場合の処理時間
print("\n== と | を使用した検索...")
start_time = time.time()
# リスト内包表記を使って、検索値の数だけ条件式を生成し、| で結合
or_condition = None
for value in search_values:
if or_condition is None:
or_condition = (large_df["値"] == value)
else:
or_condition = or_condition | (large_df["値"] == value)
large_df[or_condition]
or_time = time.time() - start_time
print(f"処理時間: {or_time:.6f} 秒")
# 結果の考察を加える
print("\n--- パフォーマンス比較結果 ---")
if isin_time < or_time:
print("今回のベンチマークでは、isin を使用した方が高速でした。")
else:
print("今回のベンチマークでは、== と | を使用した方が高速でした。")
データサイズ: 1000000 行 検索する値の数: 90 個
isin を使用した検索... 処理時間: 0.030083 秒
== と | を使用した検索... 処理時間: 0.101615 秒
--- パフォーマンス比較結果 --- 今回のベンチマークでは、isin を使用した方が高速でした。
--- パフォーマンスに関する補足 --- このベンチマーク結果は、データサイズ、検索する値の数、値の分布、実行環境など、様々な要因によって変動します。 一般的に、検索する値の数が多いほど、isin メソッドの効率性が増す傾向があります。これは、isin が内部で複数の値を効率的に検索するための最適化を行っているためです。 一方、検索する値が非常に少ない場合や、データセットが小さい場合は、== 演算子を | で結合する方法でも十分に高速な場合があります。 常に isin が高速であるとは限らないため、実際のデータと環境でベンチマークを行うことをお勧めします。
まとめ:isinメソッドを使いこなそう
Pandasのisinメソッドは、DataFrameやSeriesから「複数の特定の値」に合致するデータを効率的かつ簡潔に検索するための強力なツールです。
複数の値を検索したい場合は、迷わずisinを使いましょう。 検索したい値をリストに入れて渡すだけです。 単一の値だけを検索したい場合は、==演算子を使う方がコードが直感的になります。 これらの使い分けをマスターすることで、Pandasでのデータ検索がよりスムーズになり、データ分析の効率を上げることができます。ぜひあなたのデータ分析タスクにisinを取り入れてみてください!