【问题标题】:Pearson correlation and nan values皮尔逊相关性和 nan 值
【发布时间】:2018-07-13 11:42:24
【问题描述】:

我有两个包含数百列的 CSV_file,我想计算两个 CSV_file 的每个相同列的 Pearson 相关系数和 p 值。问题是,当一列中缺少数据“NaN”时,它会给我一个错误。当“.dropna”从列中删除 nan 值时,有时 X 和 Y 的形状不相等(基于删除的 nan 值)并且我收到此错误:

"ValueError: 操作数不能与形状一起广播 (1020,) (1016,)"

问题:如果“nan”中一个 csv 中的第 8 行,有没有办法从另一个 csv 中删除同一行,并根据两个 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') 

【问题讨论】:

    标签: python arrays numpy nan pearson-correlation


    【解决方案1】:

    这是一种解决方案。首先计算 2 个 numpy 数组的“坏”索引。然后掩码忽略那些坏索引。

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

    【讨论】:

    • 我认为坏实际上是好的(它得到了那些不是 nans 的),你可以这样做 x[bad]
    【解决方案2】:

    尝试使用 isnan 和布尔索引,而不是 dropna:

    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.
    

    希望有帮助!

    【讨论】:

    • @Amy 对不起哪一行?
    • 我试过这个,我收到了这个错误:TypeError: unsupported operand type(s) for +: 'float' and 'str'。然后我将代码更改为:[pearson_corr, pearson_p] = scipy.stats.stats.pearsonr(X[i], Y[i]),这样它就可以计算第一列的相关性,然后停下来给我这个错误:TypeError:输入类型不支持 ufunc 'isnan',并且根据强制转换规则 ''safe'',无法将输入安全地强制转换为任何支持的类型。好像循环不行!!
    • @Amy 所以我确实看到我使用掩码切片数据的方式存在一个问题,但我不知道它是否会对您有所帮助。我的建议是确保您的数据数组 (dg/df) 实际上是只有数字的矩阵。如果打印 df[2] 和 dg[2],它会打印一个 float dtype 的 numpy 数组吗?
    • 我再次收到一条错误消息,上面写着“TypeError:输入类型不支持 ufunc 'isnan',并且无法根据强制转换规则“安全”将输入安全地强制转换为任何支持的类型'”。它打印 i=1 的相关性,并在下一轮循环中,在“mask = ~np.isnan(df_sub) & ~np.isnan(dg_sub)”这一行停止,并且无法继续循环。
    • 我有一些“nan”格式的“nan”。我将它们全部更改为相同的格式,令人惊讶的是它现在可以使用了!!!!!!非常感谢。
    【解决方案3】:

    为什么不将它们组合成一个 df 并在其上使用 dropna。 所有值都将被删除。

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

    我建议获取两个 df 的列名列表,并在 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)
    

    此外,您可以只使用 csv 而不使用该 for 循环。阅读pandas.DataFrame.to_csv

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-18
      • 1970-01-01
      • 2011-09-13
      • 2018-07-23
      • 2014-11-13
      • 2017-03-17
      • 2016-04-23
      • 2021-08-29
      相关资源
      最近更新 更多