🤺
Pandasで特定の列におけるユニークな要素ごとの最後の行を取得する
はじめに
こんにちは。新卒エンジニアのwinnieです🐥
業務でPandasを触っているときに意外と難しかった(頭がどうにかなりそうだった)処理があったのでサクッと記事にしてみました。この記事は株式会社アクティブコアAdvent Calendarの5日目の記事になります!
解説
ありのままを話すと「特定の列におけるユニークな要素ごとの最後の行を取得」します。何を言っているのかわからねーと思うがおれも何を書けばいいのかわからなかったので、以下の例を見てください。
以下の表から、「 A 列におけるユニークな要素ごとの最後の行を取得」します。
| column A | column B | column C |
|---|---|---|
| 2 | 2 | 4 |
| 1 | 5 | 0 |
| 3 | 4 | 2 |
| 2 | 3 | 3 |
| 3 | 0 | 5 |
| 3 | 4 | 1 |
まず、 A 列のユニークな要素は 1 , 2 , 3 の3つになります。 A 列に 1 を含む行は1行しかないので、その行を取得します。次に、 A 列に 2 を含む行は2行ありますが、下の行を取得します。そして最後、 A 列に 3 を含む行は3行ありますが、その中の最も下の行を取得します。
| column A | column B | column C |
|---|---|---|
| 1 | 5 | 0 |
| 2 | 3 | 3 |
| 3 | 4 | 1 |
これがやりたいこと、つまり「特定の列におけるユニークな要素ごとの最後の行を取得」することです。実用的には、ユーザーごとの最新のトランザクションデータを抽出するときなどに使えます。
結論
以下のコードで実現できます。
df.groupby("A", as_index=False).last() # 基準となる列をインデックスにしない
# A B C
# 0 1 5 0
# 1 2 3 3
# 2 3 4 1
ちなみに「特定の列におけるユニークな要素ごとの最後の行以外の行を取得」する場合、以下のコードで実現できます。こちらは、ユーザーの最新のトランザクションを目的変数、それより前のトランザクションを説明変数とした時系列予測などで実用的です。
# 最後の行
df_y = df.reset_index().groupby("A", as_index=False).last() # 元データのインデックスを保持
# 最後以外の行
df_x = df[~df.index.isin(df_y["index"])] # 最後の行に含まれないデータを取得
df_x = df_x.reset_index(drop=True) # インデックスを振り直し
# 最後の行
df_y = df_y.drop("index", axis="columns") # 元データのインデックスを削除
# df_x df_y
# A B C A B C
# 0 2 2 4 0 1 5 0
# 1 3 4 2 1 2 3 3
# 2 3 0 5 2 3 4 1
おわりに
恐ろしいものの片鱗を味わったぜ…
Discussion