, если вы хотите, чтобы значение nan
было заменено скользящим средним (полное окно) на пандах серии s
, отметив из WeNYoBen , что это не продолжит вычисление скользящего среднего во время заполнения. (т. е. ваш 15,3 становится 12,0).
s.fillna(s.expanding(1).mean())
Если вы хотите, чтобы скользящее среднее обновлялось по мере заполнения nans, это решение numba
может помочь
import numpy as np
import numba
from numba import jit
@jit(nopython=True)
def rolling_fill(a):
for i, e in enumerate(a):
if np.isnan(e):
a[i] = np.mean(a[:i])
ts_values = np.array([17.0, np.NaN, 12.0, np.NaN, 18.0])
rolling_fill(ts_values)
print(ts_values)
что дает
[17. 17. 12. 15.33333333 18. ]
Вы, вероятно, могли бы улучшить это, сохраняя сумму и не звоня .mean
каждый раз.
Сложность времени
Это не log
или constant
время, так как вы должны интерполировать не более n-2
пропущенных элементов из массива длиной n
, что составляет O(n)
- но это должно быть достаточно оптимизировано (избегая повторения в native python) и вы не можете сделать теоретически лучше, но реализации вышеприведенного уровня сделают это значительно быстрее.
РЕДАКТИРОВАТЬ : Первоначально я неправильно прочитал и подумал, что вы спрашиваете об интерполяции
Вы хотели бы interpolate
серии, и панды поддерживают это напрямую.
>>> s = pd.Series([0, 1, np.nan, 5])
>>> s
0 0.0
1 1.0
2 NaN
3 5.0
dtype: float64
>>> s.interpolate()
0 0.0
1 1.0
2 3.0
3 5.0
dtype: float64
Или, если вы не хотите использовать pandas
, потому что ваш пример - ndarray
, тогда используйте numpy.interp
соответственно.