【解説】副問合せ(サブクエリ)の設定方法を学ぶ | データサイエンス100本ノック【問34〜問35 回答】
当ページのリンクには広告が含まれています。
目次
この記事の対象者
・ Pythonで副問合せ(サブクエリ)の設定方法を学びたい人
以降はデータサイエンス100本ノックの問題を題材に、副問合せ(サブクエリ)の設定方法について学んでいきます。
データサイエンス100本ノックの始め方は、以下の記事を参考にしていただければと思います。
第34問目: 検索結果に対するサブクエリ
P-034: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに売上金額(amount)を合計して全顧客の平均を求めよ。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。
まずは、query
メソッドを使って、customer_idが”Z”から始まる行以外の行を抽出します。
その後、customer_id列をグルーピングし、amount列の合計を、sumメソッドを使って計算します。
最後にmean
メソッドを用いて全顧客の平均値を求めていきます。
1 | df_receipt.query('not customer_id.str.startswith("Z")', engine='python').groupby('customer_id').amount.sum().mean() |
1 | 2547.742234529256 |
これが答えとなります。
groupby
メソッドは必要な列を抽出してから適用しなければいけません。
ちなみに、以下のようにgroupby
メソッドを適用してからquery
メソッドを用いても、AttributeError: 'DataFrameGroupBy' object has no attribute 'query'
というエラーが出力されて実行できません。
1 | df_receipt.groupby('customer_id').query('not customer_id.str.startswith("Z")', engine='python').amount.sum().mean() |
1 | --------------------------------------------------------------------------- |
groupby
メソッドは、必要な列を抽出してから適用しなければいけません。
第35問目: 条件指定でのサブクエリ
P-035: レシート明細データフレーム(df_receipt)に対し、顧客ID(customer_id)ごとに売上金額(amount)を合計して全顧客の平均を求め、平均以上に買い物をしている顧客を抽出せよ。ただし、顧客IDが”Z”から始まるのものは非会員を表すため、除外して計算すること。なお、データは10件だけ表示させれば良い。
まずは、第34問のときと同様に、df_receiptに対するcustomer_idごとにamountを合計し、全顧客の平均を求めます。
1 | df_amount_mean = df_receipt.query('not customer_id.str.startswith("Z")', engine='python').groupby('customer_id').amount.sum().mean() |
次に、顧客ID毎の売上金額の合計のデータを抽出します。
1 | df_customerid_amount_list = df_receipt.groupby('customer_id').amount.sum().reset_index() |
1 | customer_id amount |
各顧客の売上金額が、平均以上か否かを判定するには、以下のようにすればOKです。
1 | df_customerid_amount_list['amount'] >= df_amount_mean |
1 | 0 False |
このbool型の判定を、df_customerid_amount_list
のindexとして指定すれば答えが出力されます。
1 | df_customerid_amount_list[df_customerid_amount_list['amount']>=df_amount_mean] |
1 | customer_id amount |
このあたり少しわかりにくいかと思いますので、簡単な例を用いて解説します。
データフレームに対してBool型のフィルタを適用する際の注意点
例えば以下のようなデータフレームに対して、bool型でフィルタしてみたいと思います。
1 | df_temp = df_customerid_amount_list.head(4) |
1 | customer_id amount |
2つのフィルタを用意します。
1 | filter_4 = [True, False, True, False] |
この2つのフィルタをそれぞれ適用してみます。
1 | df_temp[filter_4] |
1 | customer_id amount |
このようにTrue
と指定されたindexのみが抽出されました。
では、filter_3
を適用してみます。
1 | df_temp[filter_3] |
1 | --------------------------------------------------------------------------- |
このように、フィルターを書けられる側のデータの数とbool型のフィルタの数は、一致していないといけません。
まとめ: 副問合せ(サブクエリ)の設定方法を学びました。
本記事は、「【Python】副問合せ(サブクエリ)の設定方法を学ぶ | データサイエンス100本ノック【問34〜問35 回答】」というテーマでまとめました。
groupby
メソッドは必要な列を抽出してから適用しなければいけない点や、データフレームに対してBool型のフィルタを適用する際の注意点も補足としてまとめました。