2

I have a Series like so:

>>> s = pd.Series([1,0,0,3,0,5,0,0,0])
>>> s[s==0] = pd.np.nan
>>> s
0    1.0
1    NaN
2    NaN
3    3.0
4    NaN
5    5.0
6    NaN
7    NaN
8    NaN
dtype: float64

and I'd like to 'extend' the values, as illustrated here:

>>> t = s.shift()
>>> for _ in range(100000):
...     s[s.isnull()] = t
...     if not s.isnull().any():
...             break
...     t = t.shift()
...
>>> s
0    1.0
1    1.0
2    1.0
3    3.0
4    3.0
5    5.0
6    5.0
7    5.0
8    5.0
dtype: float64

But I'd like something more vectorized and efficient. How do I do that?

Jonas Byström
  • 25,316
  • 23
  • 100
  • 147

2 Answers2

4

You are looking for fillna:

>>> s.fillna(method='ffill')
0    1.0
1    1.0
2    1.0
3    3.0
4    3.0
5    5.0
6    5.0
7    5.0
8    5.0
dtype: float64
>>>
juanpa.arrivillaga
  • 88,713
  • 10
  • 131
  • 172
1

NumPy forward filling based on np.maximum.accumulate -

def numpy_ffill(s):
    arr = s.values
    mask = np.isnan(arr)
    idx = np.where(~mask,np.arange(len(mask)),0)
    out = arr[np.maximum.accumulate(idx)]
    return pd.Series(out)

Sample run -

In [41]: s
Out[41]: 
0    1.0
1    NaN
2    NaN
3    3.0
4    NaN
5    5.0
6    NaN
7    NaN
8    NaN
dtype: float64

In [42]: numpy_ffill(s)
Out[42]: 
0    1.0
1    1.0
2    1.0
3    3.0
4    3.0
5    5.0
6    5.0
7    5.0
8    5.0
dtype: float64
Divakar
  • 218,885
  • 19
  • 262
  • 358