5

Suppose I have a dataframe, df1, that has zeros and nans:

dates = pd.date_range('20170101',periods=20)
df1 = pd.DataFrame(np.random.randint(10,size=(20,3)),index=dates,columns=['foo','bar','see'])
df1.iloc[3:12,0] = np.nan
df1.iloc[6:17,1] = 0

What's the succinct way to forward fill both zeors and nans? I tried the below:

df1 = (df1.fillna(method='ffill', inplace=True)).replace(to_replace=0, method='ffill')

AttributeError: 'NoneType' object has no attribute 'replace'
trob
  • 387
  • 1
  • 5
  • 15

2 Answers2

6

Let's use replace to replace zeros with nan then ffill:

df1.replace(0, np.nan).ffill()

Output:

            foo  bar  see
2017-01-01  2.0  1.0    4
2017-01-02  2.0  2.0    6
2017-01-03  2.0  8.0    3
2017-01-04  2.0  6.0    1
2017-01-05  2.0  8.0    4
2017-01-06  2.0  9.0    6
2017-01-07  2.0  9.0    8
2017-01-08  2.0  9.0    5
2017-01-09  2.0  9.0    8
2017-01-10  2.0  9.0    7
2017-01-11  2.0  9.0    3
2017-01-12  2.0  9.0    6
2017-01-13  5.0  9.0    4
2017-01-14  6.0  9.0    9
2017-01-15  7.0  9.0    4
2017-01-16  6.0  9.0    2
2017-01-17  2.0  9.0    5
2017-01-18  3.0  1.0    1
2017-01-19  3.0  8.0    1
2017-01-20  2.0  5.0    7
Scott Boston
  • 147,308
  • 15
  • 139
  • 187
  • Perfect. Why can't you ffill 0s? – trob Jul 12 '17 at 19:45
  • @trob Per [docs](https://pandas.pydata.org/pandas-docs/stable/generated/pandas.DataFrame.ffill.html#pandas-dataframe-ffill), "Synonym for DataFrame.fillna(method='ffill')", so it only fills NaNs. – Scott Boston Jul 12 '17 at 19:47
  • @trob The error you are getting in your question above is because of the `inplace=True' when you so that the return object from the function is None. Hence the error. However, if you remove that from your statement you still have a syntax error with replace and method='ffill'. – Scott Boston Jul 12 '17 at 20:02
2

I think @ScottBoston's answer is most idiomatic.
However, another way to do it is to use pd.DataFrame.mask

df1.mask(df1 == 0).ffill()
piRSquared
  • 285,575
  • 57
  • 475
  • 624