熊猫:如果最后一个非零值< 0:替换为 0



我有一个数据帧:

df = pd.DataFrame({'A': [1,2,-2,0,0], 'B': [0, 0, 0, 3, -2], 'C' : [0, 0, -2, 4, 0], 'D': [0, -3, 2, 1, -2]} ) 
Out: 
A  B  C  D
0  1  0  0  0
1  2  0  0 -3
2 -2  0 -2  2
3  0  3  4  1
4  0 -2  0 -2

对于每一,如果最后一个非零值<0:用 0 重新调整速度。

预期成果:


df_end = pd.DataFrame({'A': [1,2,0,0,0], 'B': [0, 0, 0, 3, 0], 'C' : [0, 0, -2, 4, 0], 'D': [0, -3, 2, 1, 0]} ) 
df_end
Out: 
A  B  C  D
0  1  0  0  0
1  2  0  0 -3
2  0  0 -2  2
3  0  3  4  1
4  0  0  0  0

我已经解决了相反的问题(如果第一个非零值<0,请替换为 0(:

df.where(df.gt(0).cummax(),0)

我现在需要它从底部查看表格。

#EDIT 正如评论中指出的,df.where(df.gt(0(.cummax((,0( 将消除所有 - 值,直到第一个正值。在我的原始数据帧中,正值和负值总是交替,所以 df.where(df.gt(0(.cummax((,0( 有效。我做了一个糟糕的示例数据帧。

让我们尝试iloc[::-1]还原df

df[~df.iloc[::-1].gt(0).cummax()] = 0

输出:

A  B  C  D
0  1  0  0  0
1  2  0  0 -3
2  0  0 -2  2
3  0  3  4  1
4  0  0  0  0

更新:正如@Ben.T评论的那样,如果你有几个负面的结局,上面的会把它们都变成零。这将解决此问题:

df = pd.DataFrame({'A': [1,2,-2,-1,0], 'B': [0, 0, 0, 3, -2], 'C' : [0, 0, -2, 4, 0], 'D': [0, -3, 2, 1, -2]} ) 
s = df.iloc[::-1]
df[s.lt(0).cumsum().eq(1) & (~s.gt(0).cummax())] = 0

输出:

A  B  C  D
0  1  0  0  0
1  2  0  0 -3
2 -2  0 -2  2
3  0  3  4  1
4  0  0  0  0

这只会将最后一个负值替换为 0

s=np.sign(df).iloc[::-1].eq(-1).idxmax()
df.values[s,df.columns.get_indexer(s.index)]=0
df
A  B  C  D
0  1  0  0  0
1  2  0  0 -3
2  0  0  0  2
3  0  3  4  1
4  0  0  0  0

最新更新