Recuperar índices de valores de NaN en un dataframe de pandas

Intento recuperar para cada fila que contiene valores de NaN todos los índices de las columnas correspondientes.

d=[[11.4,1.3,2.0, NaN],[11.4,1.3,NaN, NaN],[11.4,1.3,2.8, 0.7],[NaN,NaN,2.8, 0.7]] df = pd.DataFrame(data=d, columns=['A','B','C','D']) print df ABCD 0 11.4 1.3 2.0 NaN 1 11.4 1.3 NaN NaN 2 11.4 1.3 2.8 0.7 3 NaN NaN 2.8 0.7 

Ya he hecho lo siguiente:

  • Agrega una columna con el recuento de NaN para cada fila.
  • obtener los índices de cada fila que contienen valores de NaN

Lo que quiero (idealmente el nombre de la columna) es obtener una lista como esta:

 [ ['D'],['C','D'],['A','B'] ] 

Espero poder encontrar un camino sin hacer para cada fila la prueba para cada columna

 if df.ix[i][column] == NaN: 

Estoy buscando una forma de pandas para poder lidiar con mi enorme conjunto de datos.

Gracias por adelantado.

Otra forma, extrae las filas que son NaN:

 In [11]: df_null = df.isnull().unstack() In [12]: t = df_null[df_null] In [13]: t Out[13]: A 3 True B 3 True C 1 True D 0 True 1 True dtype: bool 

Esto te lleva a la mayor parte del camino y puede ser suficiente.
Aunque puede ser más fácil trabajar con la Serie:

 In [14]: s = pd.Series(t2.index.get_level_values(1), t2.index.get_level_values(0)) In [15]: s Out[15]: 0 D 1 C 1 D 3 A 3 B dtype: object 

por ejemplo, si quisieras las listas (aunque no creo que las necesitarías)

 In [16]: s.groupby(level=0).apply(list) Out[16]: 0 [D] 1 [C, D] 3 [A, B] dtype: object 

Debería ser eficiente usar una matriz dispersa de formato de coordenadas para obtener las coordenadas de los valores nulos:

 import scipy.sparse as sp x,y = sp.coo_matrix(df.isnull()).nonzero() print(list(zip(x,y))) [(0, 3), (1, 2), (1, 3), (3, 0), (3, 1)] 

Tenga en cuenta que estoy llamando al método nonzero para que solo se muestren las coordenadas de las entradas distintas de cero en la matriz dispersa subyacente, ya que no me importan los valores reales que son todos True .

Puede recorrer cada fila en el dataframe, crear una máscara de valores nulos y generar su índice (es decir, las columnas en el dataframe).

 lst = [] for _, row in df.iterrows(): mask = row.isnull() lst += [row[mask].index.tolist()] >>> lst [['D'], ['C', 'D'], [], ['A', 'B']] 

Otra forma más sencilla es:

 >>>df.isnull().any(axis=1) 0 True 1 True 2 False 3 True dtype: bool 

subconjunto:

 >>> bool_idx = df.isnull().any(axis=1) >>> df[bool_idx] ABCD 0 11.4 1.3 2.0 NaN 1 11.4 1.3 NaN NaN 3 NaN NaN 2.8 0.7 

para obtener el índice entero:

 >>> df[bool_idx].index Int64Index([0, 1, 3], dtype='int64')