import pandas as pd
while pd.isnull(my_series).sum() > 0:
my_series = my_series.fillna(method='ffill', limit=1).fillna(method='bfill', limit=1)
Сказать, что это будет медленно, вероятно, преуменьшение.Если бы вы хотели сделать это на большом DataFrame, я бы, вероятно, попытался реализовать его с помощью функции, которую я мог бы использовать apply
.
У меня никогда не было хорошей идеи сделать это (но я следил за этим, потому что это интересная проблема).Мне нравится другой ответ за сообразительность, но мне было любопытно, как он справился со скоростью.
def funcA(pd_series):
m = pd_series.notna()
c = m.cumsum()
def f(x):
lens = len(x.index)
a = np.arange(lens)
return a // (lens / 2) == 0
mask = c[~m].groupby(c).transform(f)
#should be removed
#mask = mask.reindex(df.index, fill_value=False)
return pd_series.where(mask, pd_series.bfill()).ffill().bfill()
def funcB(pd_series):
while pd.isnull(pd_series).sum() > 0:
pd_series = pd_series.fillna(method='ffill', limit=1).fillna(method='bfill', limit=1)
return pd_series
ps = pd.Series(np.random.randint(0,10, size=(10000)))
ps[ps < 5] = np.nan
>>> import timeit
>>> timeit.timeit('funcA(ps)', setup='from __main__ import funcA, ps', number=100)
40.9788393480012
>>> timeit.timeit('funcB(ps)', setup='from __main__ import funcB, ps', number=100)
0.4896140840010048
Ну ... это не так хорошо, как я ожидал.Небольшая серия с половиной NaN может не быть хорошим тестом, так что, может быть, попробовать что-то, что должно замкнуть цикл while?
ps = pd.Series(np.random.randint(0,100, size=(1000000)))
ps[ps < 95] = np.nan
>>> timeit.timeit('funcA(ps)', setup='from __main__ import funcA, ps', number=10)
81.64654629600045
>>> timeit.timeit('funcB(ps)', setup='from __main__ import funcB, ps', number=10)
21.431495654000173
Ну, это как минимум ближе.Мне лень больше его масштабировать, но, похоже, вам понадобится 10 ^ 7 записей с 95% + NaN, прежде чем дополнительные издержки от маскировки и аранжировки окупятся.