我有一个数据帧:
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