pandas.DataFrameのフィルタリング・条件抽出【Python tips】

Python

改訂版 Pythonユーザのための Jupyter[実践]入門 [ 池内 孝啓、片柳 薫子、@driller ]

 

こんにちは、monachan_papa です。

今回はpandas.DataFrame のフィルタリングについて解説します。
pandas.DataFrame のフィルタリングには、様々な方法があります。よって、pandas を覚えたてで、使い慣れていない間は操作に戸惑うことがあるかと思います。思うようにデータ抽出ができないシーンがあるかもしれません。
しかし、基本となる構文は以下です。

df[検索条件]

この基本構文を念頭において、DataFrame のフィルタリングを色々と巡ってみましょう。後半では、高性能な queryメソッド についても解説します。
本テーマを読むことにより、DataFrame のフィルタリング・ノウハウの定着を図ることができます

なお、本テーマはすべての解説において、毎回テスト用の DataFrame を表示させてから、フィルタリングを実施します。
これは対象の DataFrame から正しくフィルタリングができていることを即座に確認しやすくすることを目的としています。

以降の解説のために、初めにテストデータを2つ作っておきます。

# テストデータ1
import pandas as pd

data = {
    'A': [1, 2, 3, 4],
    'B': [10, 20, 30, 40],
    'C': [100, 200, 300, 400]
}

df1 = pd.DataFrame(data)
df1
A B C
0 1 10 100
1 2 20 200
2 3 30 300
3 4 40 400
# テストデータ2
import pandas as pd

data = {
    'Name': ['Ussii', 'Komako', 'Wakky', 'Martha', 'Suzuko', 'Kimino', 'Susie'],
    'Color': ['赤', '青', '黄', '緑', '紫', '橙', '桃']
}

df2 = pd.DataFrame(data)
df2
Name Color
0 Ussii
1 Komako
2 Wakky
3 Martha
4 Suzuko
5 Kimino
6 Susie

比較演算子によるフィルタリング

検索条件に、比較演算子を使用してデータ抽出することが可能です。

比較演算子
==
!=
<
<=
>
>=

以下のコードは、DataFrame 列Aの値が2以上の行を抽出しています。

# テストデータの確認
display(df1)

# フィルタリング
joken = df1.A>=2
df1[joken]
A B C
0 1 10 100
1 2 20 200
2 3 30 300
3 4 40 400
A B C
1 2 20 200
2 3 30 300
3 4 40 400

上記のコードの例は、いちいち変数joken に検索条件を設定してからフィルタリングをしています。
しかし、以下のように1行で書くことも可能です。

df1[df1.A>=2]
A B C
1 2 20 200
2 3 30 300
3 4 40 400

今回のように単純なものであれば、1行の方が簡潔明瞭で良いです。慣れてきたら、シーンに応じて使い分けると良いでしょう。

範囲指定によるフィルタリング

[]を重ねて、範囲指定することが可能です。
以下のコードは、DataFrame 列Bの値が 20 より大きく 40 より小さい行を抽出しています。

# テストデータの確認
display(df1)

# フィルタリング
joken1 = 20
A B C
0 1 10 100
1 2 20 200
2 3 30 300
3 4 40 400
A B C
2 3 30 300

複数条件を組み合わせたフィルタリング

複数条件を組み合わせたフィルタリングも可能です。
しかし、必ず以下のルールを徹底してください。

  • 各条件を () で囲む。
  • 論理積には &、論理和には | を使用する。

以下のコードは、DataFrame 列Aの値が 2 より大きい且つ、列Cの値が 400 より小さい行を抽出しています。

# テストデータの確認
display(df1)

# フィルタリング
joken = (df1.A > 2) & (df1.C < 400)
df1[joken]
A B C
0 1 10 100
1 2 20 200
2 3 30 300
3 4 40 400
A B C
2 3 30 300

正規表現によるフィルタリング

str.containsメソットを使用すると、正規表現を指定したフィルタリングができるようになります。

str.contains(パターン文字列)

以下のコードは、DataFrame Name列が 正規表現S. *と合致する行を抽出しています。

# テストデータの確認
display(df2)

# フィルタリング
joken = df2['Name'].str.contains('S.*')
df2[joken]
Name Color
0 Ussii
1 Komako
2 Wakky
3 Martha
4 Suzuko
5 Kimino
6 Susie
Name Color
4 Suzuko
6 Susie

特定条件を含む要素のフィルタリング

isinメソッドを使用すると、特定条件を含む要素のフィルタリングができるようになります。
引数には、抽出したい要素をリストで指定します。

isin(リスト)

以下のコードは、DataFrame Color列が 「赤」、「青」、「桃」を含む行を抽出しています。

# テストデータの確認
display(df2)

# フィルタリング
joken = df2.Color.isin(['赤', '青', '桃'])
df2[joken]
Name Color
0 Ussii
1 Komako
2 Wakky
3 Martha
4 Suzuko
5 Kimino
6 Susie
Name Color
0 Ussii
1 Komako
6 Susie

 


改訂版 Pythonユーザのための Jupyter[実践]入門 [ 池内 孝啓、片柳 薫子、@driller ]

 

queryメソッドを使用した高性能なフィルタリング

最後に queryメソッドを紹介します。これまで見てきたフィルタリングはすべて、最終的に df[検索条件] 形式でした。
今から紹介する queryメソッドは以下の形式になります。

df.query(‘ある列に対する検索条件式’)

queryメソッドを使用するメリットは、以下の3点であると考えます。

  1. query というだけに、分かりやすいメソッド名。
  2. 検索条件式に、複数の比較演算子を連結して記述できる。
  3. 見た目がゴチャゴチャしていない。

1は もうそのまんまです。クエリというだけに。
2は 後で詳しく説明します。
3は シンプルでコーディングの簡潔明瞭化、省力化に繋がります。

比較演算子の複数使用

Python は数学の不等式のように、複数の比較演算子を連結して記述することができます。
例えば、n = 20 のとき、 「n は 10 より大きく 40 より小さい」 は以下のように記述できます。

n = 20
10 < n < 40
True

つまり、「n は 10 より大きい且つ、40 より小さい」と同等になります。

n = 20
n > 10 and n < 40
True

以下のコードは、この言語仕様を用いたフィルタリング例です。queryメソッドを使用すると、この仕様が可能になります。
queryメソッドを使って、DataFrame 列Bが 10 より大きく、40 より小さい 行を抽出しています。

# テストデータの確認
display(df1)

# フィルタリング
df1.query('10 < B < 40')
A B C
0 1 10 100
1 2 20 200
2 3 30 300
3 4 40 400
A B C
1 2 20 200
2 3 30 300

ここで注意点があります。

queryメソッドの検索条件式は必ず引用符で囲む。

特定条件を含む要素のフィルタリング

さきほど紹介した isinメソッド による特定条件を含む要素のフィルタリング。これを queryメソッドで置き換えることができます。
以下のコードは、その置き換え版になります。

# テストデータの確認
display(df2)

# フィルタリング
df2.query("Color in ['赤', '青', '桃']")
Name Color
0 Ussii
1 Komako
2 Wakky
3 Martha
4 Suzuko
5 Kimino
6 Susie
Name Color
0 Ussii
1 Komako
6 Susie

置き換えができました。
ここで、注意すべき点があります。条件式の引用符です。ダブルクォーテーションとシングルクォーテーションをうまく使って書いてください。
私自身は基本、外側の引用符をシングルにしています。しかし、内部で引用符を使う必要がある場合は、上記のように外側ダブル、内側シングルにしています。

条件式に変数を含んだフィルタリング

queryメソッドは、条件式を引用符で囲まないといけないことから、ひとつ気になる点があります。
条件式に変数を含んだ場合の記述をどうするか?心・配・御・無・用!
変数の前に@をつけることで、変数展開が可能になります。

queryメソッド条件式における変数は @変数名 にする。

以下のコードは、条件式に変数を含んだフィルタリング例です。
条件式の左辺に DataFrame Name列、右辺に変数を使用しています。

# テストデータの確認
display(df2)

# フィルタリング
name = ['Komako', 'Martha']
df2.query('Name in @name')
Name Color
0 Ussii
1 Komako
2 Wakky
3 Martha
4 Suzuko
5 Kimino
6 Susie
Name Color
1 Komako
3 Martha

 

以上で、DataFrameのフィルタリングについての解説を終わります。

フィルタリングがスムーズにできると、データ加工・データ分析がとても捗ります。
ここで紹介したのはフィルタリングの基本になりますが、この基本が使いこなせているかどうかだけでもかなり違います。
是非、フィルタリングの名人を目指して頑張ってください。

さて、pandas をもっともっと使いこなしたい御方、さらにスキルアップをしてみたい御方は改訂版 Pythonユーザのための Jupyter[実践]入門 [ 池内 孝啓、片柳 薫子、@driller ]がたいへんオススメです。
Jupyter Lab のフル活用方法や、データ分析についてのノウハウも同時に学べて一石二鳥ならぬ、一石三鳥です。
もちろん、初心者にも大変オススメできます。Jupyter Lab自体がインタラクティブな動作確認や視覚効果が本当にすばらしいので、プログラミング学習においての理解度が触るたびに上がっていきます。どんどん触ってPython大好き人間になってもらいたいです。

 


改訂版 Pythonユーザのための Jupyter[実践]入門 [ 池内 孝啓、片柳 薫子、@driller ]

 

また、爆速で pandas を学びたい御方にはプログラミングスクールを考えるのも、ひとつの手です。独学よりも効果が出やすいですが、いかんせん投資がけっこうかかります。しかし、techgymというスクールは通うか通わないかは別として、無料のサンプルテキスト&解説動画がもらえます。これをとりあえず getしてまずは試しに体験学習するのもありでしょう。

コメント

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