Excelのオートフィルタ機能のように、Python in Excel でも pandas のオブジェクト DataFrame を使用したフィルタリングが可能です。この記事では、query メソッドとブールインデックス参照を使ったフィルタリング、データ抽出の記述方法について紹介します。
サンプルデータ
Anaconda の公式サイトにあるサンプルデータを使用して説明します。以下のページ内の「download here」のリンクからダウンロードできます。
テーブル名が「InternetSales」、データが60,398件の売上データが入っています。
構文
query メソッドの構文
DataFrame.query(expr, [inplace, kwargs])
戻り値 | DataFrame or None |
引数 | 型 | 説明 |
---|---|---|
expr | string | クエリ文字列 |
inplace (任意) | bool | 新しいDataFrameを作成するのではなく、 DataFrameを変更するかどうか Trueにすると戻り値はNoneになる デフォルト:False |
kwargs (任意) | dict | その他の設定を辞書型で指定 |
ブールインデックス参照の構文
DataFrame[List(bool) or Series]
サンプルコード
前準備
サンプルデータのブックにシートを追加し、A1セルに以下のコードを入力します。
# A1セル
# dataframeを定義
df = xl("InternetSales[#すべて]", headers = True)
Pythonの入力方法や出力種類、DataFrameの定義方法については、以下の記事で詳しく紹介しています。
【超基本】Python in Excel の使い方とルール
Python in Excel の入力方法は難しくはありませんが、Excelのワークシート関数の入力の仕方とは少し勝手が違います。この記事では、Python in Excel の入力の仕方と出力の種類、計算順序やパフォーマンスを向上させるた...
[DataFrame] xl関数の指定方法いろいろ
この記事では、DataFrameの定義、xl関数の使い方や注意点について説明します。DataFrameを使うと、Excelのセル範囲や名前、テーブル、Power Queryのデータを Python in Excel で扱えるようになります。...
抽出条件が1つ
# queryの場合
# A3セル
df1 = df.query("ProductSubcategoryName == 'Road Bikes'")
結果 8068件抽出
# ブールインデックスの場合
# A5セル
sr2 = df["ProductSubcategoryName"] == "Road Bikes"
# A6セル
df2 = df[sr2]
#df2 = df[df["ProductSubcategoryName"] == "Road Bikes"] # 一気に書いてもよい
結果 8068件抽出(queryメソッドの結果と同じ)
抽出する値が複数
その1(or でつなぐ)
# A8セル(queryメソッド)
df3 = df.query("ProductSubcategoryName == 'Mountain Bikes'"
" or ProductSubcategoryName == 'Road Bikes'"
" or ProductSubcategoryName == 'Touring Bikes'")
# A9セル(ブールインデックス)
sr4 = (df["ProductSubcategoryName"] == "Mountain Bikes") | (df["ProductSubcategoryName"] == "Road Bikes") | (df["ProductSubcategoryName"] == "Touring Bikes")
df4 = df[sr4]
結果 15205件抽出
その2(in句)
前述の例は or で条件を繋いでいますがやや冗長です。in 句を使うとすっきりとした記述で同じ結果を得られます。ブールインデックスの場合は isin メソッドを使用します。
# queryメソッド
df3 = df.query("ProductSubcategoryName "
" in ['Mountain Bikes', 'Road Bikes', 'Touring Bikes']")
# ブールインデックス
sr4 = df["ProductSubcategoryName"].isin(["Mountain Bikes", "Road Bikes", "Touring Bikes"])
df4 = df[sr4]
その3(部分一致)
部分一致や前方一致、後方一致も使えるといい感じがします。
# queryメソッド
df3_1 = df.query("ProductSubcategoryName.str.contains('Bike')") # 部分一致
df3_2 = df.query("ProductSubcategoryName.str.startswith('Bike')") # 前方一致
df3_3 = df.query("ProductSubcategoryName.str.endswith('Bikes')") # 後方一致
# ブールインデックス
df4_1 = df[ df["ProductSubcategoryName"].str.contains('Bike') ] # 部分一致
df4_2 = df[ df["ProductSubcategoryName"].str.startswith('Bike') ] # 前方一致
df4_3 = df[ df["ProductSubcategoryName"].str.endswith('Bikes') ] # 後方一致
抽出条件の項目が複数
AND条件
# A17セル(queryメソッド)
df5 = df.query("ProductSubcategoryName.str.endswith('Bikes')"
" and SalesAmount > 2500")
# A18セル(ブールインデックス)
sr6 = df["ProductSubcategoryName"].str.endswith('Bikes') & (df["SalesAmount"] > 2500)
df6 = df[sr6]
結果 1947件抽出
OR条件
# A21セル(queryメソッド)
df9 = df.query("ProductSubcategoryName == 'Road Bikes'"
" or ProductName == 'ML Road Tire'")
# A22セル(ブールインデックス)
df10 = df[ (df["ProductSubcategoryName"] == "Road Bikes") | (df["ProductName"] == "ML Road Tire") ]
結果 8994件抽出
条件の否定(NOT条件)
# A24セル(queryメソッド)
df11 = df.query("not SalesAmount > 1000")
# A25セル(ブールインデックス)
df12 = df[ ~(df["SalesAmount"] > 1000) ]
結果 49050件抽出
query メソッドの TIPS
クエリ文字列内では「@」を使って変数を参照する
query メソッドのクエリ文字列に変数を指定する場合は、変数名の前に「@」を記述します。
amount = 3500
df13 = df.query("SalesAmount > @amount")
# 以下と同じ結果が得られる
#df13 = df.query("SalesAmount > 3500")
特殊な列名はバッククォート(`)で囲む
スペースや句読点 (アンダースコアを除く) を含む列名、数字で始まる列名は、バッククォート「`」で囲みます。
df14_1 = df.query("`Sales Amount` > 3000")
df14_2 = df.query("`Sales.Amount` > 3000")
df14_3 = df.query("`1_SalesAmount` > 3000")
ブールインデックスの注意点
ブールインデックス参照で条件が複数ある場合、それぞれの条件が括弧で括られていないとエラーになります。
# エラーになる例
sr7 = df["ProductSubcategoryName"] == "Jerseys" & df["SalesAmount"] > 50.0
df7 = df[sr7]
# エラーにならない例
sr7 = (df["ProductSubcategoryName"] == "Jerseys") & (df["SalesAmount"] > 50.0)
df7 = df[sr7]
参考
Attention Required! | Cloudflare
pandas.DataFrame.query — pandas 2.2.3 documentation
DataFrameから条件を指定してデータを抽出する方法(ブールインデックス参照)【Python】 | BioTech ラボ・ノート
pandasで特定の文字列を含む行を抽出(完全一致、部分一致) | note.nkmk.me
pandas.DataFrameから特定の文字列を含む要素を持つ行を抽出する方法(完全一致・部分一致)について説明する。 条件を満たす行を抽出する方法(ブーリアンインデックス) 特定の文字列と完全一致: ==, isin() 特定 ...