【问题标题】:python scipy cannot pass a dataframe generated from class attribute?python scipy 无法传递从类属性生成的数据框?
【发布时间】:2021-09-12 20:20:33
【问题描述】:

我正在学习一些关于使用类使我的代码更容易修改的知识。我正在定义一个 ml_setup 类,该类从单独的函数中调用 spearman 计算。

class ml_setup:
    def __init__(self, df, dropcols, ycol, **kwargs ):
        self.ycol = ycol
        self.df = df  
        if 'stratify' in kwargs:
            self.stratify = kwargs['stratify']
        else:
            self.stratify = None
        self.train_Y = df[ycol]
        self.train_X = df.drop(columns=dropcols)
        if 'seed' in kwargs:
            self.seed = kwargs['seed']
        else:
            self.seed = self.seed_gen()
        if 'test' in kwargs:
            self.test = kwargs['test']
        else:
            self.test = 0.3
        if 'final_model' in kwargs:
            self.final_model = kwargs['final_model']
        else:
            self.final_model = None

    def seed_gen(self):
        seed = np.random.randint(0,2**32 - 1)
        return seed
    def linear_reg(self, positive=False):
        self.regr = linear_model.LinearRegression(positive=positive)    
        if self.final_model is None:
            self.X_train, self.X_test, self.y_train, self.y_test = train_test_split(self.train_X, self.train_Y, test_size=self.test, random_state=self.seed, shuffle=True, stratify=self.stratify)        
            #for test/train
            self.regr.fit(self.X_train, self.y_train)
            self.predictions = self.regr.predict(self.X_test)
            #print(y_test)
            #print(self.predictions)
            #print(self.y_test[self.ycol])
            self.p, self.s = pearson_stat(self.y_test[self.ycol], self.predictions, print_out='no')
            self.r2 = r_squared(self.y_test, self.predictions)

pearson_stat 函数如下所示,

def pearson_stat (x_data, y_data, print_out='no'):
    import scipy.stats as ss
    p = ss.pearsonr(x_data, y_data)
    s = ss.spearmanr(x_data, y_data)
    if print_out == 'yes':
        print('Pearson rho = {:.4f}, P = {:.4g}'
                  .format(*p))
        print('Spearman r = {:.4f}, P = {:.4g}'
                  .format(*s))
    return p[0], s[0]

如果我按照以下方式将 x 和 y 传递给 pearson_stat 函数,则此代码可以完美运行。

a, s = pearson_stat(ml_mods[seed].y_test['exp_val'],ml_mods[seed].y_test['exp_val'])

但是如果我现在从类属性中设置“exp_val”,它就不起作用了。给我以下错误。

a, s = pearson_stat(ml_mods[seed].y_test[ml_mods[seed].ycol],ml_mods[seed].y_test[ml_mods[seed].ycol])

xmean = x.mean(dtype=dtype)
  File "../anaconda3/envs/py3/lib/python3.6/site-packages/numpy/core/_methods.py", line 160, in _mean
     ret = umr_sum(arr, axis, dtype, out, keepdims)
TypeError: No loop matching the specified signature and casting was found for ufunc add

你能帮我理解一下吗?

【问题讨论】:

  • 检查更改的参数。有什么不同。不要指望我们仅仅通过阅读代码就能推断出这一点。
  • 我所做的唯一更改基本上是使用“ml_mods[seed].ycol”添加列名。 ml_mods[seed] 类中的 ycol 属性基本上是一个包含一个元素的列表。 ml_mods[seed].ycol 等于 ['exp_val'] 所以从技术上讲,我的问题是为什么当我通过直接提及列表而不是通过类的属性传递列表来专门传递它时,python 不会引发错误。
  • 我希望您测试或验证的是当您进行更改时会发生什么。什么ml_mods[seed].y_test[ml_mods[seed].ycol]?不是你想要的或希望的,但它实际上是。例如,使用列名索引数据框与使用包含相同名称的列表对其进行索引是不同的。 pearson_stat 得到了不同的东西。发现什么是你的工作!
  • 哦,我明白了。我才意识到发生了什么。我只查看了 ml_mods[seed].y_test[ml_mods[seed].ycol] 和 ml_mods[seed].y_test['exp_val'] Bothe 的输出(从外观上看)。但现在我检查了输出的类型。它实际上给出了两种不同的数据类型 > type(ml_mods[seed].y_test[ml_mods[seed].ycol]) > type(ml_mods[seed].y_test['exp_val ']) 我想知道为什么当 ['exp_val'] 和 ml_mods[seed].ycol 都具有类型列表时,“ml_mods[seed].ycol”会导致 DataFrame 的输出形式
  • 顺便说一句,非常感谢您指导我的回答!

标签: python dataframe numpy scipy


【解决方案1】:

因此,在@hpaulj 的指导下,我意识到我调用该列的方式导致了 DataFrame 而不是 Series。对于 Pearson 计算,我需要 Series 形式的数据(即类似数组)。

type(ml_mods[seed].y_test[ml_mods[seed].ycol]) 
<class 'pandas.core.frame.DataFrame'> 
type(ml_mods[seed].y_test['exp_val']) 
<class 'pandas.core.series.Series'>

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-12-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-03-28
    • 2013-11-13
    • 1970-01-01
    • 2019-11-06
    相关资源
    最近更新 更多