簡體   English   中英

如何使用 Pandas 從 df 創建等級

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

筆記:

  • instead of the somewhat hacky string cumsum method I'm using here, you could probably use a list accumulation function and then use a pandas split-apply-combine method to do the counting in the lambda function
  • you would then apply a state change boolean, and do a cumsum on the state change boolean, filtered/grouped on the state value (so, how many state changes do we have for any given state)
  • state 更改 boolean 是這樣完成的: someDF["StateChange"] = someDF["state"].= someDF["state"].shift()
  • 因此,對於給定行的給定 state,您將計算前幾行中發生了多少 state 更改。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM