usar tablas recorrer para notebook leer hacer graficar funciones filtrar datos data con como python pandas scipy correlation

tablas - pandas python



correlación de columnas de pandas con significación estadística (4)

Puede usar las funciones de correlación scipy.stats para obtener el valor p.

Por ejemplo, si está buscando una correlación tal como la correlación Pearson, puede usar la función pearsonr .

from scipy.stats import pearsonr pearsonr([1, 2, 3], [4, 3, 7])

Da salida

(0.7205766921228921, 0.48775429164459994)

Donde el primer valor en la tupla es el valor de correlación, y el segundo es el valor p.

En su caso, puede usar la función dropna pandas para eliminar primero los valores NaN .

df_clean = df[[''column1'', ''column2'']].dropna() pearsonr(df_clean[''column1''], df_clean[''column2''])

¿Cuál es la mejor manera, dado un marco de datos de pandas, df, para obtener la correlación entre sus columnas df.1 y df.2 ?

No quiero que el resultado cuente las filas con NaN , lo que hace la correlación pandas incorporada. Pero también quiero que pvalue un pvalue o un error estándar, que el built-in no pvalue .

SciPy parece quedar atrapado por los NaN, aunque creo que informa la importancia.

Ejemplo de datos:

1 2 0 2 NaN 1 NaN 1 2 1 2 3 -4 3 4 1.3 1 5 NaN NaN


He intentado resumir la lógica en una función, puede que no sea el enfoque más eficiente, pero le proporcionará un resultado similar a pandas df.corr (). Para usar esto simplemente ponga la siguiente función en su código y llámela proporcionando su objeto de marco de datos, es decir. corr_pvalue (your_dataframe) .

Redondeé los valores a 4 decimales, en caso de que desee una salida diferente, cambie el valor en la función de redondeo.

def corr_pvalue(df): from scipy.stats import pearsonr import numpy as np import pandas as pd numeric_df = df.dropna()._get_numeric_data() cols = numeric_df.columns mat = numeric_df.values arr = np.zeros((len(cols),len(cols)), dtype=object) for xi, x in enumerate(mat.T): for yi, y in enumerate(mat.T[xi:]): arr[xi, yi+xi] = map(lambda _: round(_,4), pearsonr(x,y)) arr[yi+xi, xi] = arr[xi, yi+xi] return pd.DataFrame(arr, index=cols, columns=cols)

Lo he probado con pandas v0.18.1


Para calcular todos los valores p de una vez , puede usar la siguiente función calculate_pvalues :

df = pd.DataFrame({''A'':[1,2,3], ''B'':[2,5,3], ''C'':[5,2,1], ''D'':[''text'',2,3] }) calculate_pvalues(df)

  • El resultado es similar al corr() (pero con valores p):

    A B C A 0 0.7877 0.1789 B 0.7877 0 0.6088 C 0.1789 0.6088 0

  • los valores p se redondean a 4 decimales

  • La columna D se ignora ya que contiene texto.

A continuación está el código de la función :

from scipy.stats import pearsonr import pandas as pd def calculate_pvalues(df): df = df.dropna()._get_numeric_data() dfcols = pd.DataFrame(columns=df.columns) pvalues = dfcols.transpose().join(dfcols, how=''outer'') for r in df.columns: for c in df.columns: pvalues[r][c] = round(pearsonr(df[r], df[c])[1], 4) return pvalues


La respuesta proporcionada por @Shashank es agradable. Sin embargo, si quieres una solución en pandas puros, te puede gustar esto:

import pandas as pd from pandas.io.data import DataReader from datetime import datetime import scipy.stats as stats gdp = pd.DataFrame(DataReader("GDP", "fred", start=datetime(1990, 1, 1))) vix = pd.DataFrame(DataReader("VIXCLS", "fred", start=datetime(1990, 1, 1))) #Do it with a pandas regression to get the p value from the F-test df = gdp.merge(vix,left_index=True, right_index=True, how=''left'') vix_on_gdp = pd.ols(y=df[''VIXCLS''], x=df[''GDP''], intercept=True) print(df[''VIXCLS''].corr(df[''GDP'']), vix_on_gdp.f_stat[''p-value''])

Resultados:

-0.0422917932738 0.851762475093

Los mismos resultados que la función de estadísticas:

#Do it with stats functions. df_clean = df.dropna() stats.pearsonr(df_clean[''VIXCLS''], df_clean[''GDP''])

Resultados:

(-0.042291793273791969, 0.85176247509284908)

Para extender a más variables, te doy un enfoque feo basado en bucle:

#Add a third field oil = pd.DataFrame(DataReader("DCOILWTICO", "fred", start=datetime(1990, 1, 1))) df = df.merge(oil,left_index=True, right_index=True, how=''left'') #construct two arrays, one of the correlation and the other of the p-vals rho = df.corr() pval = np.zeros([df.shape[1],df.shape[1]]) for i in range(df.shape[1]): # rows are the number of rows in the matrix. for j in range(df.shape[1]): JonI = pd.ols(y=df.icol(i), x=df.icol(j), intercept=True) pval[i,j] = JonI.f_stat[''p-value'']

Resultados de rho:

GDP VIXCLS DCOILWTICO GDP 1.000000 -0.042292 0.870251 VIXCLS -0.042292 1.000000 -0.004612 DCOILWTICO 0.870251 -0.004612 1.000000

Resultados de pval:

[[ 0.00000000e+00 8.51762475e-01 1.11022302e-16] [ 8.51762475e-01 0.00000000e+00 9.83747425e-01] [ 1.11022302e-16 9.83747425e-01 0.00000000e+00]]