[英]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.