¿Cómo zscore normalizar la columna pandas con nans?

Tengo un dataframe de pandas con una columna de valores reales que quiero normalizar zscore:

>> a array([ nan, 0.0767, 0.4383, 0.7866, 0.8091, 0.1954, 0.6307, 0.6599, 0.1065, 0.0508]) >> df = pandas.DataFrame({"a": a}) 

El problema es que un solo valor nan hace que todo el array nan :

 >> from scipy.stats import zscore >> zscore(df["a"]) array([ nan, nan, nan, nan, nan, nan, nan, nan, nan, nan]) 

¿Cuál es la forma correcta de aplicar zscore (o una función equivalente no de scipy) a una columna de un dataframe de pandas y hacer que ignore los valores de nan ? Me gustaría que tuviera la misma dimensión que la columna original con np.nan para valores que no se pueden normalizar

Edición : tal vez la mejor solución es usar scipy.stats.nanmean y scipy.stats.nanstd ? No veo por qué los grados de libertad deben cambiarse por std para este propósito:

 zscore = lambda x: (x - scipy.stats.nanmean(x)) / scipy.stats.nanstd(x) 

Bueno, las versiones de los pandas' de mean y std le entregarán a Nan así que podrías simplemente calcular de esa manera (para obtener el mismo valor que scipy zscore, creo que necesitas usar ddof = 0 en std ):

 df['zscore'] = (df.a - df.a.mean())/df.a.std(ddof=0) print df a zscore 0 NaN NaN 1 0.0767 -1.148329 2 0.4383 0.071478 3 0.7866 1.246419 4 0.8091 1.322320 5 0.1954 -0.747912 6 0.6307 0.720512 7 0.6599 0.819014 8 0.1065 -1.047803 9 0.0508 -1.235699 

Podrías ignorar los nans usando isnan .

 z = a # initialise array for zscores z[~np.isnan(a)] = zscore(a[~np.isnan(a)]) pandas.DataFrame({'a':a,'Zscore':z}) Zscore a 0 NaN NaN 1 -1.148329 0.0767 2 0.071478 0.4383 3 1.246419 0.7866 4 1.322320 0.8091 5 -0.747912 0.1954 6 0.720512 0.6307 7 0.819014 0.6599 8 -1.047803 0.1065 9 -1.235699 0.0508