python – cómo calcular la matriz de correlación con nans en la matriz de datos

No puedo encontrar una función que calcule una matriz de coeficientes de correlación para matrices que contienen observaciones para más de dos variables cuando hay NaN en los datos. Hay funciones que hacen esto para pares de variables (o simplemente enmascaran los arreglos usando ~ is.nan ()). Pero al usar estas funciones haciendo un bucle sobre un gran número de variables, calcular la correlación para cada par puede llevar mucho tiempo.

Así que lo intenté por mi cuenta y pronto me di cuenta de que la complejidad de hacerlo es una cuestión de la normalización adecuada de la Covarianza. Estaría muy interesado en sus opiniones sobre cómo hacerlo.

Aquí está el código:

def nancorr(X,nanfact=False): X = X - np.nanmean(X,axis=1,keepdims = True)*np.ones((1,X.shape[1])) if nanfact: mask = np.isnan(X).astype(int) fact = X.shape[1] - np.dot(mask,mask.T) - 1 X[np.isnan(X)] = 0 if nanfact: cov = np.dot(X,XT)/fact else: cov = np.dot(X,XT) d = np.diag(cov) return cov/np.sqrt(np.multiply.outer(d,d)) 

La función asume que cada fila es una variable. Básicamente es un código ajustado de corrpyeff () de numpy. Creo que hay tres maneras de hacer esto:

(1) Para cada par de variables, toma solo aquellas observaciones para las cuales ni una ni la otra variable es NaN. Este es posiblemente el más preciso, pero también el más difícil de progtwigr si desea realizar el cálculo para más de un par simultáneamente y no está cubierto en el código anterior. Sin embargo, ¿por qué desechar la información sobre la media y la varianza de cada variable, solo porque la entrada correspondiente de otra variable es NaN? Por lo tanto, otras dos opciones.

(2) Hemos degradado cada variable por medio de su nanmean y la varianza de cada variable es su nanvarianza. Para la covarianza, cada observación donde una u otra variable es NaN, pero no ambas, es una observación de no covariación y, por lo tanto, se establece en cero. El factor de la covarianza es entonces 1 / (número de observación donde no ambas variables son NaN – 1), denotado por n. Ambas variaciones en el denominador del coeficiente de correlación son factorizadas por su número correspondiente de observaciones no NaN menos 1, denotadas por n1 y n2 respectivamente. Esto se logra estableciendo nanfact = True en la función anterior.

(3) Uno puede desear que la covarianza y las varianzas tengan el mismo factor que en el caso del coeficiente de correlación sin NaN. La única manera significativa de hacer esto aquí (si la opción (1) no es factible), es simplemente ignorar (1 / n) / sqrt (1 / n1 * n2). Como este número es menor que uno, los coeficientes de correlación estimados serán mayores (en valor absoluto) que en (2), pero se mantendrán entre -1,1. Esto se logra estableciendo nanfact = False.

Me interesaría mucho su opinión sobre los enfoques (2) y (3) y, especialmente, me gustaría mucho ver una solución para (1) sin el uso de bucles.

Creo que el método que estás buscando es corr() de pandas. Por ejemplo, un dataframe de la siguiente manera. También puede referirse a esta pregunta. ¿Cómo obtener de manera eficiente la matriz de correlación (con valores p) de un dataframe con valores NaN?

 import pandas as pd df = pd.DataFrame({'A': [2, None, 1, -4, None, None, 3], 'B': [None, 1, None, None, 1, 3, None], 'C': [2, 1, None, 2, 2.1, 1, 0], 'D': [-2, 1.1, 3.2, 2, None, 1, None]}) df 
  ABCD 0 2 NaN 2 -2 1 NaN 1 1 1.1 2 1 NaN NaN 3.2 3 -4 NaN 2 2 4 NaN 1 2.1 NaN 5 NaN 3 1 1 6 3 NaN 0 NaN 
 rho = df.corr() rho 
  ABCD A 1.000000 NaN -0.609994 -0.441784 B NaN 1.0 -0.500000 -1.000000 C -0.609994 -0.5 1.000000 -0.347928 D 0.041204 -1.0 -0.347928 1.000000