Interpolar (o extrapolar) solo pequeñas lagunas en el marco de datos de pandas
Tengo un DataFrame de pandas con tiempo como índice (1 min Freq) y varias columnas de datos. A veces los datos contienen NaN. Si es así, quiero interpolar solo si la brecha no es superior a 5 minutos. En este caso, esto sería un máximo de 5 NaN consecutivos. Los datos pueden verse así (varios casos de prueba, que muestran los problemas):
import numpy as np
import pandas as pd
from datetime import datetime
start = datetime(2014,2,21,14,50)
data = pd.DataFrame(index=[start + timedelta(minutes=1*x) for x in range(0, 8)],
data={'a': [123.5, np.NaN, 136.3, 164.3, 213.0, 164.3, 213.0, 221.1],
'b': [433.5, 523.2, 536.3, 464.3, 413.0, 164.3, 213.0, 221.1],
'c': [123.5, 132.3, 136.3, 164.3] + [np.NaN]*4,
'd': [np.NaN]*8,
'e': [np.NaN]*7 + [2330.3],
'f': [np.NaN]*4 + [2763.0, 2142.3, 2127.3, 2330.3],
'g': [2330.3] + [np.NaN]*7,
'h': [2330.3] + [np.NaN]*6 + [2777.7]})
Se lee así:
In [147]: data
Out[147]:
a b c d e f g h
2014-02-21 14:50:00 123.5 433.5 123.5 NaN NaN NaN 2330.3 2330.3
2014-02-21 14:51:00 NaN 523.2 132.3 NaN NaN NaN NaN NaN
2014-02-21 14:52:00 136.3 536.3 136.3 NaN NaN NaN NaN NaN
2014-02-21 14:53:00 164.3 464.3 164.3 NaN NaN NaN NaN NaN
2014-02-21 14:54:00 213.0 413.0 NaN NaN NaN 2763.0 NaN NaN
2014-02-21 14:55:00 164.3 164.3 NaN NaN NaN 2142.3 NaN NaN
2014-02-21 14:56:00 213.0 213.0 NaN NaN NaN 2127.3 NaN NaN
2014-02-21 14:57:00 221.1 221.1 NaN NaN 2330.3 2330.3 NaN 2777.7
Estoy consciente dedata.interpolate()
pero tiene varios defectos, ya que produce este resultado, lo cual es bueno para las columnas a-e, pero para las columnas f-h falla por diferentes razones:
a b c d e f g \
2014-02-21 14:50:00 123.5 433.5 123.5 NaN NaN NaN 2330.3
2014-02-21 14:51:00 129.9 523.2 132.3 NaN NaN NaN 2330.3
2014-02-21 14:52:00 136.3 536.3 136.3 NaN NaN NaN 2330.3
2014-02-21 14:53:00 164.3 464.3 164.3 NaN NaN NaN 2330.3
2014-02-21 14:54:00 213.0 413.0 164.3 NaN NaN 2763.0 2330.3
2014-02-21 14:55:00 164.3 164.3 164.3 NaN NaN 2142.3 2330.3
2014-02-21 14:56:00 213.0 213.0 164.3 NaN NaN 2127.3 2330.3
2014-02-21 14:57:00 221.1 221.1 164.3 NaN 2330.3 2330.3 2330.3
h
2014-02-21 14:50:00 2330.300000
2014-02-21 14:51:00 2394.214286
2014-02-21 14:52:00 2458.128571
2014-02-21 14:53:00 2522.042857
2014-02-21 14:54:00 2585.957143
2014-02-21 14:55:00 2649.871429
2014-02-21 14:56:00 2713.785714
2014-02-21 14:57:00 2777.700000
f) La brecha consta de 4 minutos de NaN al principio, deben reemplazarse por ese valor 2763.0 (es decir, extrapolar hacia atrás en el tiempo)
g) El espacio es más largo que 5 minutos pero aún así se extrapola
h) El espacio es más largo que 5 minutos pero aún así el espacio está interpolado.
Entiendo esas razones, por supuesto, en ninguna parte especifiqué que no debería interpolar espacios más largos de 5 minutos. Entiendo queinterpolate
solo extrapola hacia adelante en el tiempo, pero quiero que también extrapole hacia atrás en el tiempo. ¿Hay algún método conocido que pueda usar para mi problema, sin reinventar la rueda?
Editar: el métododata.interpolate
acepta el parámetro de entradalimit
, que define el número máximo de NaN consecutivos que se sustituirán por interpolación. Pero esto todavía interpola hasta el límite, pero quiero seguir con todos los NaN en ese caso.