2017-05-30 105 views
3

如何将列中的零值替换为列的前一行值为零的另一列的同一行中的值,即仅替换尚未遇到非零的位置的值? 例如:给定的列abc一个数据帧:熊猫:将零值替换为另一列的值

+----+-----+-----+----+ 
| | a | b | c | 
|----+-----+-----|----| 
| 0 | 2 | 0 | 0 | 
| 1 | 5 | 0 | 0 | 
| 2 | 3 | 4 | 0 | 
| 3 | 2 | 0 | 3 | 
| 4 | 1 | 8 | 1 | 
+----+-----+-----+----+ 

b替换零个值和ca值,其中前一值是零

+----+-----+-----+----+ 
| | a | b | c | 
|----+-----+-----|----| 
| 0 | 2 | 2 | 2 | 
| 1 | 5 | 5 | 5 | 
| 2 | 3 | 4 | 3 | 
| 3 | 2 | 0 | 3 | <-- zero in this row is not replaced because of 
| 4 | 1 | 8 | 1 |  non-zero value (4) in row before it. 
+----+-----+-----+----+ 

回答

1
In [90]: (df[~df.apply(lambda c: c.eq(0) & c.shift().fillna(0).eq(0))] 
    ...: .fillna(pd.DataFrame(np.tile(df.a.values[:, None], df.shape[1]), 
    ...:       columns=df.columns, index=df.index)) 
    ...: .astype(int) 
    ...:) 
Out[90]: 
    a b c 
0 2 2 2 
1 5 5 5 
2 3 4 3 
3 2 0 3 
4 1 8 1 

说明:

In [91]: df[~df.apply(lambda c: c.eq(0) & c.shift().fillna(0).eq(0))] 
Out[91]: 
    a b c 
0 2 NaN NaN 
1 5 NaN NaN 
2 3 4.0 NaN 
3 2 0.0 3.0 
4 1 8.0 1.0 

现在我们可以填写NaN的从下方与DF的相应值(这是建立在3级联a列):

In [92]: pd.DataFrame(np.tile(df.a.values[:, None], df.shape[1]), columns=df.columns, index=df.index) 
Out[92]: 
    a b c 
0 2 2 2 
1 5 5 5 
2 3 3 3 
3 2 2 2 
4 1 1 1 
+0

真的很好的解释。谢谢。这里唯一的问题是,如果'b'没有0,它将使用它来填充'c',而不是使用'a'中的值。不是吗? – DougKruger

+0

@DougKruger,我想你在说我以前的答案,它使用'.ffill(axis = 1)'。我已经更新了它 - 请在解释中检查 – MaxU

+0

,b和c中的所有值已被c完全覆盖。 – DougKruger