wake-up-neo.net

Pearson-Korrelation und Nanowerte

Ich habe zwei CSV-Dateien mit Hunderten von Spalten, und ich möchte den Pearson-Korrelationskoeffizienten und den p-Wert für jede gleiche Spalte von zwei CSV-Dateien berechnen. Das Problem ist, dass, wenn in einer Spalte "NaN" fehlt, ein Fehler angezeigt wird. Wenn ".dropna" nan-Werte aus Spalten entfernt, sind die Formen von X und Y manchmal nicht gleich (basierend auf entfernten nan-Werten) und ich erhalte diesen Fehler:

"ValueError: Operanden konnten nicht zusammen mit Shapes (1020,) (1016,) gesendet werden."

Frage: Wenn Zeile # 8 in einem CSV in "nan", gibt es eine Möglichkeit, dieselbe Zeile auch aus dem anderen CSV zu entfernen und die Analyse für jede Spalte anhand von Zeilen durchzuführen, die Werte aus beiden CSV-Dateien enthalten?

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') 
5
Amy

Hier ist eine Lösung. Berechnen Sie zuerst die "schlechten" Indizes für Ihre 2 numpy Arrays. Dann Maske, um diese schlechten Indizes zu ignorieren.

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.])
5
jpp

Versuchen Sie, anstelle von dropna die isnanische und die boolsche Indexierung zu verwenden:

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.

Hoffentlich hilft das!

1
c-wilson

Warum kombinieren Sie sie nicht zu einem einzigen df und verwenden Sie einfach dropna darauf. Alle Werte werden entfernt.

newdf=pd.concat([df, dg], axis=1, sort=False)
newdf.dropna()

Ich schlage vor, eine Liste der Spaltennamen von beiden df zu erhalten und diese in der for-Schleife zu verwenden:

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)

sie können auch einfach eine CSV-Datei ohne die for-Schleife erstellen. read pandas.DataFrame.to_csv

0
Ohad