[英]Conditional counting in pandas df
我有一個dataframe的股價:
df = pd.DataFrame([100, 101, 99, 100,105,104,106], columns=['P'])
我想創建一個計數器列,如果當前價格高於前一行的價格,則計數,但如果當前價格低於前一行的價格,則僅在超過該價格后再次計數(如水印)。 下面是所需的列:
df['counter'] = [np.nan, 1, 1, 1,2,2,3]
所以第二排的價格是101超過100,所以計數器是1,然后價格下降到99又回到100,但是計數器還是1,因為我們還沒有達到101的價格(也就是水印) ,然后一旦我們在第 4 行超過 101,價格為 105,計數器變為 2,然后價格再次下降到 104,所以我們保持在 2,然后當它變為 106 時,我們將計數器增加到 3。
算法:
找出每行(包括當前行)的當前最大先前觀察到的值。
查看前一行的最大先前觀察值是多少。
每次這兩個值之間存在差異時,我們就知道在當前行中已經命中了一個新的水印。
計算新水印被擊中次數的累積總和。
df["current_observed_max"] = df["p"].cummax() df["previous_observed_max"] = df["current_observed_max"].shift(1) df["is_new_watermark"] =(df["current_observed_max"].= df["previous_observed_max"]).astype(int) df["counter"] = df["is_new_watermark"].cumsum()
有了這個,您可能需要減去 1,具體取決於您希望如何處理第一個觀察到的數字。
另一種方法:查找行值是否等於累積最大值和 cumsum() 以創建唯一組
df['newP']=(df['P'].cummax()==df['P']).cumsum()-1
P newP
0 100 0
1 101 1
2 99 1
3 100 1
4 105 2
5 104 2
6 106 3
一個非常簡單有效的方法是結合pandas.factorize
和cumsum
:
df['counter'] = pd.factorize(df['P'].cummax())[0]
Output:
P counter
0 100 0
1 101 1
2 99 1
3 100 1
4 105 2
5 104 2
6 106 3
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.