[英]How to create a rank from a df with Pandas
我有一個按時間順序排序的表格,其中包含 state 和每個日期前的金額。 該表如下所示:
日期 | State | 數量 |
---|---|---|
2022 年 1 月 1 日 | 1 | 1233.11 |
2022 年 2 月 1 日 | 1 | 16.11 |
2022 年 3 月 1 日 | 2 | 144.58 |
2022 年 4 月 1 日 | 1 | 298.22 |
2022 年 5 月 1 日 | 2 | 152.34 |
2022 年 6 月 1 日 | 2 | 552.01 |
2022 年 7 月 1 日 | 3 | 897.25 |
要生成數據集:
pd.DataFrame({'date': ["01/08/2022","02/08/2022","03/08/2022","04/08/2022","05/08/2022","06/08/2022","07/08/2022","08/08/2022","09/08/2022","10/08/2022","11/08/2022"], 'state' : [1,1,2,2,3,1,1,2,2,2,1],'amount': [144,142,166,144,142,166,144,142,166,142,166]})
我想添加一個名為 rank 的列,當 state 更改時,該列會增加。 所以如果你有二十次 state 1,它只是排名 1。如果你有 state 2,當 state 1 再次出現時,排名增加。 也就是說,如果連續兩天 State 為 1,則 Rank 為 1。然后,出現另一個 state。 當 State 1 再次出現時,Rank 將增加到 2。
我想添加一個名為“Rank”的列,如果給定的 state 再次出現,該列的值會自行增加。 state 連續出現的次數就像一個計數器。 那它,如果 state。 一個例子如下:
日期 | State | 數量 | 秩 |
---|---|---|---|
2022 年 1 月 1 日 | 1 | 1233.11 | 1 |
2022 年 2 月 1 日 | 1 | 16.11 | 1 |
2022 年 3 月 1 日 | 2 | 144.58 | 1 |
2022 年 4 月 1 日 | 1 | 298.22 | 2 |
2022 年 5 月 1 日 | 2 | 152.34 | 2 |
2022 年 6 月 1 日 | 2 | 552.01 | 2 |
2022 年 7 月 1 日 | 3 | 897.25 | 1 |
這也可以理解為:
日期 | State | 數量 | Rank_State1 | Rank_State2 | Rank_State2 |
---|---|---|---|---|---|
2022 年 1 月 1 日 | 1 | 1233.11 | 1 | ||
2022 年 2 月 1 日 | 1 | 16.11 | 1 | ||
2022 年 3 月 1 日 | 2 | 144.58 | 1 | ||
2022 年 4 月 1 日 | 1 | 298.22 | 2 | ||
2022 年 5 月 1 日 | 2 | 152.34 | 2 | ||
2022 年 6 月 1 日 | 2 | 552.01 | 2 | ||
2022 年 7 月 1 日 | 3 | 897.25 | 1 |
有誰知道如何從上一個表開始構建該 Rank 列?
您的問題屬於 state 變化累積的一般類別,這表明使用累積和和布爾值的方法。
這是您可以做到的一種方法-也許不是最優雅的,但我認為它可以滿足您的需要
import pandas as pd
someDF = pd.DataFrame({'date': ["01/08/2022","02/08/2022","03/08/2022","04/08/2022","05/08/2022","06/08/2022","07/08/2022","08/08/2022","09/08/2022","10/08/2022","11/08/2022"], 'state' : [1,1,2,2,3,1,1,2,2,2,1],'amount': [144,142,166,144,142,166,144,142,166,142,166]})
someDF["StateAccumulator"] = someDF["state"].apply(str).cumsum()
def groupOccurrence(someRow):
sa = someRow["StateAccumulator"]
s = str(someRow["state"])
stateRank = len("".join([i if i != '' else " " for i in sa.split(s)]).split())\
+ int((sa.split(s)[0] == '') or (int(sa.split(s)[-1] == '')) and sa[-1] != s)
return stateRank
someDF["Rank"] = someDF.apply(lambda x: groupOccurrence(x), axis=1)
如果我理解正確,這就是您想要的結果 - “排名”旨在表示給定的一組連續狀態出現的次數:
date state amount StateAccumulator Rank
0 01/08/2022 1 144 1 1
1 02/08/2022 1 142 11 1
2 03/08/2022 2 166 112 1
3 04/08/2022 2 144 1122 1
4 05/08/2022 3 142 11223 1
5 06/08/2022 1 166 112231 2
6 07/08/2022 1 144 1122311 2
7 08/08/2022 2 142 11223112 2
8 09/08/2022 2 166 112231122 2
9 10/08/2022 2 142 1122311222 2
10 11/08/2022 1 166 11223112221 3
筆記:
someDF["StateChange"] = someDF["state"].= someDF["state"].shift()
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.