[Python] Pandas – DataFrameを複数条件でフィルタリングする方法
PandasのDataFrameを複数条件でフィルタリングするには、各条件を括弧で囲み、論理演算子(&
:AND、|
:OR)を使用します。
例えば、df[(df['列1'] > 10) & (df['列2'] == '値')]
のように記述します。
&
や|
を使う際は、各条件を括弧で囲む必要があります。
また、条件を反転させるには~
を使用します。
DataFrameのフィルタリングとは
PandasのDataFrameは、行と列からなるデータ構造で、データの操作や分析に非常に便利です。
フィルタリングは、特定の条件に基づいてDataFrameからデータを抽出するプロセスを指します。
これにより、必要な情報を効率的に取得することができます。
DataFrameの基本構造
DataFrameは、以下の要素から構成されています。
要素 | 説明 |
---|---|
行 | データの各エントリを表す。 |
列 | データの属性や特徴を表す。 |
インデックス | 各行を識別するためのラベル。 |
データ型 | 各列に格納されるデータの型(整数、浮動小数点、文字列など)。 |
以下は、簡単なDataFrameの例です。
import pandas as pd
# サンプルデータの作成
data = {
'名前': ['田中', '鈴木', '佐藤', '山田'],
'年齢': [25, 30, 22, 35],
'性別': ['男', '女', '男', '女']
}
# DataFrameの作成
df = pd.DataFrame(data)
print(df)
名前 年齢 性別
0 田中 25 男
1 鈴木 30 女
2 佐藤 22 男
3 山田 35 女
フィルタリングの基本的な考え方
フィルタリングは、特定の条件を満たす行を選択するプロセスです。
Pandasでは、条件を指定してDataFrameをフィルタリングすることができます。
基本的な考え方は以下の通りです。
- 条件を指定する:特定の列に対して条件を設定します。
- 条件に基づいて行を選択する:指定した条件を満たす行だけを抽出します。
例えば、年齢が30歳以上の人をフィルタリングする場合、以下のように記述します。
# 年齢が30歳以上の行をフィルタリング
filtered_df = df[df['年齢'] >= 30]
print(filtered_df)
名前 年齢 性別
1 鈴木 30 女
3 山田 35 女
単一条件でのフィルタリングの復習
単一条件でのフィルタリングは、特定の列に対して1つの条件を設定して行を選択する方法です。
例えば、性別が「男」の人をフィルタリングする場合、以下のように記述します。
# 性別が「男」の行をフィルタリング
male_df = df[df['性別'] == '男']
print(male_df)
名前 年齢 性別
0 田中 25 男
2 佐藤 22 男
このように、単一条件でのフィルタリングを使うことで、特定の条件に合致するデータを簡単に抽出することができます。
複数条件でのフィルタリング方法
複数条件でのフィルタリングは、DataFrameから特定の条件を満たす行を選択する際に非常に便利です。
Pandasでは、論理演算子を使用して複数の条件を組み合わせることができます。
論理演算子を使ったフィルタリング
Pandasでは、以下の論理演算子を使用して複数条件でフィルタリングを行います。
演算子 | 説明 |
---|---|
& | AND条件(両方の条件を満たす) |
| | OR条件(いずれかの条件を満たす) |
~ | NOT条件(条件を満たさない) |
AND条件(&)を使ったフィルタリング
AND条件を使用すると、複数の条件をすべて満たす行を抽出できます。
例えば、年齢が30歳以上かつ性別が「女」の人をフィルタリングする場合、以下のように記述します。
# 年齢が30歳以上かつ性別が「女」の行をフィルタリング
filtered_df_and = df[(df['年齢'] >= 30) & (df['性別'] == '女')]
print(filtered_df_and)
名前 年齢 性別
1 鈴木 30 女
OR条件(|)を使ったフィルタリング
OR条件を使用すると、いずれかの条件を満たす行を抽出できます。
例えば、年齢が25歳未満または性別が「男」の人をフィルタリングする場合、以下のように記述します。
# 年齢が25歳未満または性別が「男」の行をフィルタリング
filtered_df_or = df[(df['年齢'] < 25) | (df['性別'] == '男')]
print(filtered_df_or)
名前 年齢 性別
0 田中 25 男
2 佐藤 22 男
NOT条件(~)を使ったフィルタリング
NOT条件を使用すると、特定の条件を満たさない行を抽出できます。
例えば、性別が「女」でない人をフィルタリングする場合、以下のように記述します。
# 性別が「女」でない行をフィルタリング
filtered_df_not = df[~(df['性別'] == '女')]
print(filtered_df_not)
名前 年齢 性別
0 田中 25 男
2 佐藤 22 男
複数条件を組み合わせる際の注意点
複数条件を組み合わせてフィルタリングを行う際には、いくつかの注意点があります。
括弧の重要性
複数の条件を組み合わせる場合、条件を正しく評価するために括弧を使用することが重要です。
括弧を使わないと、意図しない結果になることがあります。
例えば、以下のように記述することが推奨されます。
# 正しい書き方
filtered_df = df[(df['年齢'] >= 30) & (df['性別'] == '女')]
演算子の優先順位
Pandasでは、論理演算子の優先順位が異なります。
&
(AND)は|
(OR)よりも優先されます。
そのため、複数の条件を組み合わせる際には、演算子の優先順位を理解しておくことが重要です。
演算子の優先順位を考慮し、必要に応じて括弧を使用して条件を明確にすることが大切です。
複数条件フィルタリングの具体例
複数条件でのフィルタリングは、データ分析において非常に重要な技術です。
ここでは、数値、文字列、日付の条件を使った具体的なフィルタリングの例を紹介します。
数値条件を使ったフィルタリング
数値条件を使ったフィルタリングでは、数値データに基づいて行を選択します。
範囲指定でのフィルタリング
特定の範囲内の値を持つ行をフィルタリングすることができます。
例えば、年齢が25歳以上35歳以下の人をフィルタリングする場合、以下のように記述します。
# 年齢が25歳以上35歳以下の行をフィルタリング
filtered_df_range = df[(df['年齢'] >= 25) & (df['年齢'] <= 35)]
print(filtered_df_range)
名前 年齢 性別
0 田中 25 男
1 鈴木 30 女
3 山田 35 女
複数列を使ったフィルタリング
複数の列を組み合わせてフィルタリングすることも可能です。
例えば、年齢が30歳以上かつ性別が「男」の人をフィルタリングする場合、以下のように記述します。
# 年齢が30歳以上かつ性別が「男」の行をフィルタリング
filtered_df_multiple_columns = df[(df['年齢'] >= 30) & (df['性別'] == '男')]
print(filtered_df_multiple_columns)
名前 年齢 性別
(該当者なし)
文字列条件を使ったフィルタリング
文字列条件を使ったフィルタリングでは、文字列データに基づいて行を選択します。
部分一致でのフィルタリング
文字列の部分一致を使ってフィルタリングすることができます。
例えば、名前に「田」が含まれる人をフィルタリングする場合、以下のように記述します。
# 名前に「田」が含まれる行をフィルタリング
filtered_df_partial_match = df[df['名前'].str.contains('田')]
print(filtered_df_partial_match)
名前 年齢 性別
0 田中 25 男
3 山田 35 女
正規表現を使ったフィルタリング
正規表現を使用して、より複雑な条件でフィルタリングすることも可能です。
例えば、名前が「田」で始まる人をフィルタリングする場合、以下のように記述します。
# 名前が「田」で始まる行をフィルタリング
filtered_df_regex = df[df['名前'].str.match('^田')]
print(filtered_df_regex)
名前 年齢 性別
0 田中 25 男
3 山田 35 女
日付条件を使ったフィルタリング
日付条件を使ったフィルタリングでは、日付データに基づいて行を選択します。
日付範囲でのフィルタリング
特定の日付範囲内のデータをフィルタリングすることができます。
以下の例では、特定の期間内の日付を持つデータをフィルタリングします。
import pandas as pd
# サンプルデータの作成
data = {
'名前': ['田中', '鈴木', '佐藤', '山田'],
'年齢': [25, 30, 22, 35],
'性別': ['男', '女', '男', '女'],
'登録日': pd.to_datetime(['2023-01-01', '2023-02-15', '2023-03-10', '2023-04-20'])
}
# DataFrameの作成
df_dates = pd.DataFrame(data)
# 2023年2月1日から2023年3月31日までの登録日を持つ行をフィルタリング
filtered_df_date_range = df_dates[(df_dates['登録日'] >= '2023-02-01') & (df_dates['登録日'] <= '2023-03-31')]
print(filtered_df_date_range)
名前 年齢 性別 登録日
1 鈴木 30 女 2023-02-15
2 佐藤 22 男 2023-03-10
特定の曜日や月でのフィルタリング
特定の曜日や月に基づいてフィルタリングすることも可能です。
例えば、登録日が月曜日の人をフィルタリングする場合、以下のように記述します。
# 登録日が月曜日の行をフィルタリング
filtered_df_monday = df_dates[df_dates['登録日'].dt.dayofweek == 0]
print(filtered_df_monday)
名前 年齢 性別 登録日
(該当者なし)
このように、複数条件を使ったフィルタリングを活用することで、データ分析をより効果的に行うことができます。
複数条件フィルタリングの応用
複数条件でのフィルタリングには、さまざまな方法があります。
ここでは、Pandasの便利なメソッドを使ったフィルタリングの応用例を紹介します。
isin()を使ったフィルタリング
isin()メソッド
を使用すると、特定の値のリストに含まれる行を簡単にフィルタリングできます。
例えば、特定の名前の人をフィルタリングする場合、以下のように記述します。
# 特定の名前を持つ行をフィルタリング
names_to_filter = ['田中', '佐藤']
filtered_df_isin = df[df['名前'].isin(names_to_filter)]
print(filtered_df_isin)
名前 年齢 性別
0 田中 25 男
2 佐藤 22 男
between()を使ったフィルタリング
between()メソッド
を使用すると、特定の範囲内の値を持つ行をフィルタリングできます。
例えば、年齢が25歳から30歳の人をフィルタリングする場合、以下のように記述します。
# 年齢が25歳から30歳の行をフィルタリング
filtered_df_between = df[df['年齢'].between(25, 30)]
print(filtered_df_between)
名前 年齢 性別
0 田中 25 男
1 鈴木 30 女
query()メソッドを使ったフィルタリング
query()メソッド
を使用すると、条件を文字列として記述することでフィルタリングができます。
例えば、年齢が30歳以上かつ性別が「女」の人をフィルタリングする場合、以下のように記述します。
# queryメソッドを使ったフィルタリング
filtered_df_query = df.query('年齢 >= 30 and 性別 == "女"')
print(filtered_df_query)
名前 年齢 性別
1 鈴木 30 女
loc[]を使ったフィルタリング
loc[]
を使用すると、行と列を指定してデータを抽出できます。
例えば、年齢が30歳以上の人の名前と性別をフィルタリングする場合、以下のように記述します。
# locを使ったフィルタリング
filtered_df_loc = df.loc[df['年齢'] >= 30, ['名前', '性別']]
print(filtered_df_loc)
名前 性別
1 鈴木 女
3 山田 女
複数条件での欠損値処理
データに欠損値が含まれている場合、フィルタリングを行う前に欠損値を処理することが重要です。
例えば、年齢が欠損している行を除外し、年齢が30歳以上の人をフィルタリングする場合、以下のように記述します。
# 欠損値を除外してフィルタリング
filtered_df_no_na = df[df['年齢'].notna() & (df['年齢'] >= 30)]
print(filtered_df_no_na)
名前 年齢 性別
1 鈴木 30 女
3 山田 35 女
このように、Pandasのさまざまなメソッドを活用することで、複数条件でのフィルタリングをより効率的に行うことができます。
複数条件フィルタリングのパフォーマンス最適化
データ分析において、フィルタリングのパフォーマンスは非常に重要です。
特に大規模なデータセットを扱う場合、効率的なフィルタリングを行うことで、処理時間を大幅に短縮できます。
ここでは、複数条件フィルタリングのパフォーマンスを最適化する方法を紹介します。
フィルタリングの順序によるパフォーマンスの違い
フィルタリングの条件を設定する際、条件の順序がパフォーマンスに影響を与えることがあります。
一般的に、データのサイズを小さくする条件を先に適用することで、後続の条件の処理が軽くなります。
例えば、年齢が特定の範囲内のデータを最初にフィルタリングし、その後に性別でフィルタリングすることで、全体の処理時間を短縮できます。
# 年齢でフィルタリングした後に性別でフィルタリング
filtered_df_optimized = df[(df['年齢'] >= 25) & (df['年齢'] <= 35) & (df['性別'] == '女')]
print(filtered_df_optimized)
このように、条件の順序を工夫することで、パフォーマンスを向上させることができます。
インデックスを活用した高速化
Pandasでは、DataFrameにインデックスを設定することで、データの検索やフィルタリングを高速化できます。
特に、頻繁にフィルタリングを行う列にインデックスを設定することが推奨されます。
以下のように、set_index()メソッド
を使用してインデックスを設定できます。
# 年齢列をインデックスに設定
df_indexed = df.set_index('年齢')
# インデックスを使ったフィルタリング
filtered_df_indexed = df_indexed.loc[30:35]
print(filtered_df_indexed)
インデックスを活用することで、フィルタリングの速度が向上し、大規模データの処理が効率的になります。
メモリ効率を考慮したフィルタリング
メモリ効率を考慮することも、フィルタリングのパフォーマンス最適化において重要です。
特に、大規模なデータセットを扱う場合、必要なデータだけをメモリに読み込むことが推奨されます。
例えば、read_csv()メソッド
のusecols
引数を使用して、必要な列だけを読み込むことができます。
# 必要な列だけを読み込む
df_memory_efficient = pd.read_csv('data.csv', usecols=['名前', '年齢', '性別'])
また、データ型を適切に設定することで、メモリ使用量を削減できます。
例えば、整数型の列をint8
やint16
に変更することで、メモリの使用効率を向上させることができます。
# 年齢列のデータ型をint8に変更
df['年齢'] = df['年齢'].astype('int8')
このように、メモリ効率を考慮したフィルタリングを行うことで、パフォーマンスを最適化し、よりスムーズなデータ分析が可能になります。
まとめ
この記事では、Pandasを使用したDataFrameの複数条件フィルタリングについて、基本的な方法から応用、パフォーマンス最適化のテクニックまで幅広く解説しました。
特に、論理演算子を用いたフィルタリングや、isin()
、between()
、query()メソッド
などの便利な機能を活用することで、効率的にデータを抽出する方法を紹介しました。
これらのテクニックを実践することで、データ分析の精度を高め、より効果的な意思決定を行うことが可能になります。
ぜひ、実際のデータセットに対してこれらのフィルタリング技術を試してみて、データ分析のスキルを向上させてください。