hacer pandas DataFrame a un dict y dropna

Tengo algunos pandas DataFrame con NaNs en él. Me gusta esto:

import pandas as pd import numpy as np raw_data={'A':{1:2,2:3,3:4},'B':{1:np.nan,2:44,3:np.nan}} data=pd.DataFrame(raw_data) >>> data AB 1 2 NaN 2 3 44 3 4 NaN 

Ahora quiero hacer un dictado y al mismo tiempo eliminar los NaN. El resultado debería verse así:

 {'A': {1: 2, 2: 3, 3: 4}, 'B': {2: 44.0}} 

Pero el uso de la función pandas to_dict me da un resultado como este:

 >>> data.to_dict() {'A': {1: 2, 2: 3, 3: 4}, 'B': {1: nan, 2: 44.0, 3: nan}} 

Entonces, ¿cómo hacer un dictado de DataFrame y deshacerse de los NaN?

escribe una función insired por to_dict desde pandas

 import pandas as pd import numpy as np from pandas import compat def to_dict_dropna(self,data): return dict((k, v.dropna().to_dict()) for k, v in compat.iteritems(data)) raw_data={'A':{1:2,2:3,3:4},'B':{1:np.nan,2:44,3:np.nan}} data=pd.DataFrame(raw_data) dict=to_dict_dropna(data) 

y como resultado obtienes lo que quieres:

 >>> dict {'A': {1: 2, 2: 3, 3: 4}, 'B': {2: 44.0}} 

Hay muchas maneras de lograr esto. Pasé un tiempo evaluando el rendimiento en un dataframe no tan grande (70k). Aunque la respuesta de @ der_die_das_jojo es funcional, también es bastante lenta.

La respuesta sugerida por esta pregunta en realidad resulta ser 5 veces más rápida en un gran dataframe.

En mi dataframe de prueba ( df ):

Método anterior:

 %time [ v.dropna().to_dict() for k,v in df.iterrows() ] CPU times: user 51.2 s, sys: 0 ns, total: 51.2 s Wall time: 50.9 s 

Otro método lento:

 %time df.apply(lambda x: [x.dropna()], axis=1).to_dict(orient='rows') CPU times: user 1min 8s, sys: 880 ms, total: 1min 8s Wall time: 1min 8s 

El método más rápido que pude encontrar:

 %time [ {k:v for k,v in m.items() if pd.notnull(v)} for m in df.to_dict(orient='rows')] CPU times: user 14.5 s, sys: 176 ms, total: 14.7 s Wall time: 14.7 s 

El formato de esta salida es un diccionario orientado a filas, es posible que deba hacer ajustes si desea que el formulario esté orientado a columnas en la pregunta.

Muy interesado si alguien encuentra una respuesta aún más rápida a esta pregunta.

Puedes usar un dictado de dictado y pasar sobre las columnas.

 {col:df[col].dropna().to_dict() for col in df}