簡體   English   中英

Pandas:基於另一列的前一行值的條件累積和

[英]Pandas: Conditional cumsum based on previous row value of another column

我想對一列求和,但求和前每一行的值必須與另一列的值進行檢查,如果另一列的值較小,則該值加起來而不是第一列的前一行。 考慮這個 dataframe:

df = pd.DataFrame({'X': [0,1,0,1,1,0,0,0,0,1,1,1,0,1], 'Y': [0, 0, 1, 1, 1, 2, 3, 4, 4, 4, 4, 4, 5, 5]})
    X   Y
0   0   0
1   1   0
2   0   1
3   1   1
4   1   1
5   0   2
6   0   3
7   0   4
8   0   4
9   1   4
10  1   4
11  1   4
12  0   5
13  1   5

現在,我想對 X 進行 cumsum,但是如果 Y 小於上一行中的 X,它將相加而不是 X。例如,X 的第二行的 cumsum 結果為 1,但因為 Y 的第二行中的 0小於1,我們替換它。 那么第三行的 cumsum 將是 0 而不是 1。我使用“for循環”編寫了如下代碼,但對於大型數據集它根本沒有效率:

df['Z'] = 0
for index in range(1,len(df)):
    df.loc[index, 'Z'] = min(df.loc[index, 'X']+df.loc[index-1, 'Z'], df.loc[index, 'Y'])

Z 的預期結果是:

    X   Y   Z
0   0   0   0
1   1   0   0
2   0   1   0
3   1   1   1
4   1   1   1
5   0   2   1
6   0   3   1
7   0   4   1
8   0   4   1
9   1   4   2
10  1   4   3
11  1   4   4
12  0   5   4
13  1   5   5

我會很感激有人可以提出一種更有效的方法。

由於您的“專業 cumsum”的結果取決於先前的結果,因此您不能使用實際的cumsum function。

相反,您應該使用 function “帶內存”(記住上一個返回值)並在下一次調用中使用它(用於下一行)。

0行在這里是一個特例。 由於第0行沒有Z列的先前值,即使在您的代碼中您將第一行的結果保留為0 ,所以我在 function 中做了同樣的事情(見下文)。

其他行根據您的算法計算。

要計算您的“專業 cumsum”,請定義以下 function:

def myCumSum(row):
    if row.name == 0:
        myCumSum.prev = 0
    else:
        myCumSum.prev = min(row.X + myCumSum.prev, row.Y)
    return myCumSum.prev

關於row.name的一點解釋:它實際上是當前行的索引,我的解決方案依賴於源 DataFrame 具有默認索引的事實,即從0開始的連續數字。

然后將其應用於每一行並將結果保存在新列( Z )中:

df['Z'] = df.apply(myCumSum, axis=1)

結果是:

    X  Y  Z
0   0  0  0
1   1  0  0
2   0  1  0
3   1  1  1
4   1  1  1
5   0  2  1
6   0  3  1
7   0  4  1
8   0  4  1
9   1  4  2
10  1  4  3
11  1  4  4
12  0  5  4
13  1  5  5

暫無
暫無

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

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