36

I have the following dataframe:

index = range(14)
data = [1, 0, 0, 2, 0, 4, 6, 8, 0, 0, 0, 0, 2, 1]
df = pd.DataFrame(data=data, index=index, columns = ['A'])

How can I fill the zeros with the previous non-zero value using pandas? Is there a fillna that is not just for "NaN"?.

The output should look like:

[1, 1, 1, 2, 2, 4, 6, 8, 8, 8, 8, 8, 2, 1]

(This question was asked before here Fill zero values of 1d numpy array with last non-zero values but he was asking exclusively for a numpy solution)

Community
  • 1
  • 1
Gabriel
  • 3,737
  • 11
  • 30
  • 48

2 Answers2

66

You can use replace with method='ffill'

In [87]: df['A'].replace(to_replace=0, method='ffill')
Out[87]:
0     1
1     1
2     1
3     2
4     2
5     4
6     6
7     8
8     8
9     8
10    8
11    8
12    2
13    1
Name: A, dtype: int64

To get numpy array, work on values

In [88]: df['A'].replace(to_replace=0, method='ffill').values
Out[88]: array([1, 1, 1, 2, 2, 4, 6, 8, 8, 8, 8, 8, 2, 1], dtype=int64)
Zero
  • 74,117
  • 18
  • 147
  • 154
  • if looking to replace the value with another, say 1 do `df['A'].replace(to_replace=0,value = 1)` – Chidi Jan 25 '19 at 10:57
  • This is not replacing 0 values in the dataframe, instead it is excluding those dataframe values and returning the rest of the dataframe. Can someone please suggest a better option? – Abhay Bh Mar 24 '20 at 12:35
-1

This is a better answer to the previous one, since the previous answer returns a dataframe which hides all zero values.

Instead, if you use the following line of code -

df['A'].mask(df['A'] == 0).ffill(downcast='infer')

Then this resolves the problem. It replaces all 0 values with previous values.

Abhay Bh
  • 139
  • 1
  • 4
  • 16