Tengo dos archivos CSV con cientos de columnas y quiero calcular el coeficiente de correlación de Pearson y el valor p para cada columna de dos archivos CSV. El problema es que cuando faltan datos "NaN" en una columna, me da un error. Cuando ".dropna" elimina el valor nan de las columnas, a veces las formas de X e Y no son iguales (según los valores nan eliminados) y recibo este error:
"ValueError: los operandos no se pudieron transmitir junto con las formas (1020,) (1016,)"
Pregunta: Si la fila #8 en un csv en "nan", ¿hay alguna forma de eliminar la misma fila del otro csv también y hacer el análisis para cada columna en función de las filas que tienen valores de ambos archivos csv?
import pandas as pd import scipy import csv import numpy as np from scipy import stats df = pd.read_csv ("D:/Insitu-Daily.csv",header = None) dg = pd.read_csv ("D:/Model-Daily.csv",header = None) pearson_corr_set = [] pearson_p_set = [] for i in range(1,df.shape[1]): X= df[i].dropna(axis=0, how='any') Y= dg[i].dropna(axis=0, how='any') [pearson_corr, pearson_p] = scipy.stats.stats.pearsonr(X, Y) pearson_corr_set = np.append(pearson_corr_set,pearson_corr) pearson_p_set = np.append(pearson_p_set,pearson_p) with open('D:/Results.csv','wb') as file: str1 = ",".join(str(i) for i in np.asarray(pearson_corr_set)) file.write(str1) file.write('\n') str1 = ",".join(str(i) for i in np.asarray(pearson_p_set)) file.write(str1) file.write('\n')Aquí hay una solución. Primero calcule los índices "malos" para sus 2 matrices numpy. Luego enmascare para ignorar esos malos índices.
x = np.array([5, 1, 6, 9, 10, np.nan, 1, 1, np.nan]) y = np.array([4, 4, 5, np.nan, 6, 2, 1, 8, 1]) bad = ~np.logical_or(np.isnan(x), np.isnan(y)) np.compress(bad, x) # array([ 5., 1., 6., 10., 1., 1.]) np.compress(bad, y) # array([ 4., 4., 5., 6., 1., 8.])En lugar de dropna, intente usar isnan y la indexación booleana:
for i in range(1, df.shape[1]): df_sub = df[i] dg_sub = dg[i] mask = ~np.isnan(df_sub) & ~np.isnan(dg_sub) # mask array is now true where ith rows of df and dg are NOT nan. X = df_sub[mask] # this returns a 1D array of length mask.sum() Y = df_sub[mask] ... your code continues.¡Espero que ayude!
¿Por qué no combinarlos en un solo df y simplemente usar dropna en él? todos los valores serán eliminados.
newdf=pd.concat([df, dg], axis=1, sort=False) newdf.dropna()Sugiero obtener una lista de nombres de columna de ambos df y usarla en el bucle for:
dfnames=list(df.columns.values) dgnames=list(dg.columns.values) for i in range(len(dfnames)): X= newdf[dfnames[i]].dropna(axis=0, how='any') Y= newdf[dgnames[i]].dropna(axis=0, how='any') [pearson_corr, pearson_p] = scipy.stats.stats.pearsonr(X, Y) pearson_corr_set = np.append(pearson_corr_set,pearson_corr) pearson_p_set = np.append(pearson_p_set,pearson_p)Además, puede simplemente csv sin ese bucle for. leer pandas.DataFrame.to_csv