Identificando NaNs consecutivos con pandas

Estoy leyendo un montón de archivos CSV (datos de medición para niveles de agua a lo largo del tiempo) para hacer varios análisis y visualizaciones en ellos.

Debido a varias razones fuera de mi control, estas series de tiempo a menudo tienen datos faltantes, así que hago dos cosas:

Los cuento en total con

Rlength=len(RainD) #counts everything, including NaN Rcount=RainD.count() #counts only valid numbers NaN_Number=Rlength-Rcount 

y descartar el conjunto de datos si tengo más datos faltantes que un cierto umbral:

 Percent_Data=Rlength/100 Five_Percent=Percent_Data*5 if NaN_Number > Five_Percent: ... 

Si el número de NaN es suficientemente pequeño, me gustaría llenar los huecos con

 RainD.level=RainD.level.fillna(method='pad',limit=2) 

Y ahora para el tema: sus datos mensuales, así que si tengo más de 2 NaN consecutivos, también quiero descartar los datos, ya que eso significaría que “adivino” una temporada completa, o incluso más.

La documentación para fillna no menciona realmente lo que sucede cuando hay más NaN consecutivos que mi limit=2 especificado limit=2 , pero cuando veo RainD.describe() antes y después ...fillna... y compárelo con la base CSV, está claro que llena los primeros 2 NaN, y luego deja el rest como está, en lugar de cometer errores.

Así que, larga historia corta:

¿Cómo identifico un número de NaN consecutivos con pandas, sin un bucle no pandas complicado y que consume mucho tiempo?

Puede utilizar varias condiciones booleanas para comprobar si el valor actual y el valor anterior son NaN :

 In [3]: df = pd.DataFrame({'a':[1,3,np.NaN, np.NaN, 4, np.NaN, 6,7,8]}) df Out[3]: a 0 1 1 3 2 NaN 3 NaN 4 4 5 NaN 6 6 7 7 8 8 In [6]: df[(df.a.isnull()) & (df.a.shift().isnull())] Out[6]: a 3 NaN 

Si desea encontrar dónde ocurren las NaNs consecutivas donde está buscando más de 2, podría hacer lo siguiente:

 In [38]: df = pd.DataFrame({'a':[1,2,np.NaN, np.NaN, np.NaN, 6,7,8,9,10,np.NaN,np.NaN,13,14]}) df Out[38]: a 0 1 1 2 2 NaN 3 NaN 4 NaN 5 6 6 7 7 8 8 9 9 10 10 NaN 11 NaN 12 13 13 14 In [41]: df.a.isnull().astype(int).groupby(df.a.notnull().astype(int).cumsum()).sum() Out[41]: a 1 0 2 3 3 0 4 0 5 0 6 0 7 2 8 0 9 0 Name: a, dtype: int32