やましなぶろぐ

SQLの分析関数:Window Function RankをPandasで実現する

transform関数

自作問題を作成してSQLとPandasで回答します

🕒 Last mod: 2021-02-16


1. Window Function Rank

SQLの分析関数の活用方法ではRankが頻出でWeb上の情報も豊富です。

今回はPandasでの実装をためしてみます。

「データサイエンティスト協会スキル定義委員」の「データサイエンス100本ノック(構造化データ加工編)」を利用しています

2. レシート明細データフレーム(df_receipt)の売上金額(amount)を日付(sales_ymd)ごとに大きい順にランクづけせよ。

自作の問題です。

3. SQLでの回答例

answer.sql
select
  sales_ymd,
  amount,
  rank()
  over (
    partition by sales_ymd
    order by amount desc
  )
  amount_rank
from
  receipt
limit 10
;
output
 sales_ymd | amount | amount_rank
-----------+--------+-------------
  20170101 |   4880 |           1
  20170101 |   2400 |           2
  20170101 |   2200 |           3
  20170101 |   2200 |           3
  20170101 |   1400 |           5
  20170101 |   1200 |           6
  20170101 |   1100 |           7
  20170101 |   1100 |           7
  20170101 |    980 |           9
  20170101 |    918 |          10
(10 rows)

4. pandasの回答例

answer.py
answer = (
    df_receipt[[
        'sales_ymd',
        'amount',
    ]]
    .sort_values(
        by=['sales_ymd', 'amount'],
        ascending=[True, False]
    )
    .assign(
        amount_rank=lambda x:(
            x
            .groupby('sales_ymd')
            .amount
            .transform(
                'rank',
                method='min',
                ascending=False,
            )
        )
    )
)
output
        sales_ymd  amount  amount_rank
25785    20170101    4880          1.0
84345    20170101    2400          2.0
32610    20170101    2200          3.0
102861   20170101    2200          3.0
46658    20170101    1400          5.0
7556     20170101    1200          6.0
37331    20170101    1100          7.0
39659    20170101    1100          7.0
65951    20170101     980          9.0
34756    20170101     918         10.0