![](/img/trans.png)
[英]Replace pandas zero value with ffill non-zero, if the subsequent value is non-zero
[英]Pandas: if last non-zero value < 0: replace with 0
我有一个 dataframe:
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) 将消除所有 - 值,直到第一个正数。 在我原来的 Dataframe 中,正值和负值总是交替的,所以 df.where(df.gt(0).cummax(),0) 有效。 我做了一个不好的例子dataframe。
让我们尝试iloc[::-1]
恢复df
:
df[~df.iloc[::-1].gt(0).cummax()] = 0
Output:
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
Output:
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
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.