¿Enumerar los pares de correlación más altos de una matriz de correlación grande en Pandas?

¿Cómo encuentras las principales correlaciones en una matriz de correlación con Pandas? Hay muchas respuestas sobre cómo hacer esto con R ( Mostrar correlaciones como una lista ordenada, no como una matriz grande o una forma eficiente de obtener pares altamente correlacionados de un conjunto de datos grande en Python o R ), pero me pregunto cómo hacerlo. con pandas? En mi caso, la matriz es 4460×4460, por lo que no se puede hacer visualmente.

Puede usar DataFrame.values para obtener una matriz numpy de los datos y luego usar las funciones NumPy como argsort() para obtener los pares más correlacionados.

Pero si desea hacer esto en pandas, puede unstack y order el dataframe:

 import pandas as pd import numpy as np shape = (50, 4460) data = np.random.normal(size=shape) data[:, 1000] += data[:, 2000] df = pd.DataFrame(data) c = df.corr().abs() s = c.unstack() so = s.sort_values(kind="quicksort") print so[-4470:-4460] 

Aquí está la salida:

 2192 1522 0.636198 1522 2192 0.636198 3677 2027 0.641817 2027 3677 0.641817 242 130 0.646760 130 242 0.646760 1171 2733 0.670048 2733 1171 0.670048 1000 2000 0.742340 2000 1000 0.742340 dtype: float64 

La respuesta de @HRYRY es perfecta. Solo construyendo sobre esa respuesta agregando un poco más de lógica para evitar la duplicación y las autocorrelaciones y la clasificación adecuada:

 import pandas as pd d = {'x1': [1, 4, 4, 5, 6], 'x2': [0, 0, 8, 2, 4], 'x3': [2, 8, 8, 10, 12], 'x4': [-1, -4, -4, -4, -5]} df = pd.DataFrame(data = d) print("Data Frame") print(df) print() print("Correlation Matrix") print(df.corr()) print() def get_redundant_pairs(df): '''Get diagonal and lower triangular pairs of correlation matrix''' pairs_to_drop = set() cols = df.columns for i in range(0, df.shape[1]): for j in range(0, i+1): pairs_to_drop.add((cols[i], cols[j])) return pairs_to_drop def get_top_abs_correlations(df, n=5): au_corr = df.corr().abs().unstack() labels_to_drop = get_redundant_pairs(df) au_corr = au_corr.drop(labels=labels_to_drop).sort_values(ascending=False) return au_corr[0:n] print("Top Absolute Correlations") print(get_top_abs_correlations(df, 3)) 

Eso da el siguiente resultado:

 Data Frame x1 x2 x3 x4 0 1 0 2 -1 1 4 0 8 -4 2 4 8 8 -4 3 5 2 10 -4 4 6 4 12 -5 Correlation Matrix x1 x2 x3 x4 x1 1.000000 0.399298 1.000000 -0.969248 x2 0.399298 1.000000 0.399298 -0.472866 x3 1.000000 0.399298 1.000000 -0.969248 x4 -0.969248 -0.472866 -0.969248 1.000000 Top Absolute Correlations x1 x3 1.000000 x3 x4 0.969248 x1 x4 0.969248 dtype: float64 

Pocas líneas de solución sin pares de variables redundantes:

 corr_matrix = df.corr().abs() #the matrix is symmetric so we need to extract upper triangle matrix without diagonal (k = 1) sol = (corr_matrix.where(np.triu(np.ones(corr_matrix.shape), k=1).astype(np.bool)) .stack() .sort_values(ascending=False) #first element of sol series is the pair with the bigest correlation 

Combinando algunas características de las respuestas de @HYRY y @ arun, puede imprimir las principales correlaciones para el df en una sola línea usando:

 df.corr().unstack().sort_values().drop_duplicates() 

Nota: el único inconveniente es que si tiene correlaciones 1.0 que no son una variable en sí misma, la drop_duplicates() eliminaría

Use itertools.combinations para obtener todas las correlaciones únicas de la matriz de correlación propia de los pandas .corr() , genere una lista de listas y realícela en un DataFrame para usar ‘.sort_values’. Establecer ascending = True para mostrar las correlaciones más bajas en la parte superior

corrank toma un DataFrame como argumento porque requiere .corr() .

  def corrank(X): import itertools df = pd.DataFrame([[(i,j),X.corr().loc[i,j]] for i,j in list(itertools.combinations(X.corr(), 2))],columns=['pairs','corr']) print(df.sort_values(by='corr',ascending=False)) corrank(X) # prints a descending list of correlation pair (Max on top) 

Utilice el código siguiente para ver las correlaciones en orden descendente.

 # See the correlations in descending order corr = df.corr() # df is the pandas dataframe c1 = corr.abs().unstack() c1.sort_values(ascending = False) 

Muchas buenas respuestas aquí. La forma más fácil que encontré fue una combinación de algunas de las respuestas anteriores.

 corr = corr.where(np.triu(np.ones(corr.shape), k=1).astype(np.bool)) corr = corr.unstack().transpose()\ .sort_values(by='column', ascending=False)\ .dropna()