【问题标题】:`ValueError: too many values to unpack (expected 4)` with `scipy.stats.linregress``ValueError: 使用 `scipy.stats.linregress` 解压的值太多(预计 4 个)`
【发布时间】:2016-12-08 01:53:20
【问题描述】:

我知道当设置的变量值多于函数返回的值时,会出现此错误消息 (ValueError: too many values to unpack (expected 4))。

scipy.stats.linregress 根据 scipy 文档 (http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html) 返回 5 个值。

下面是一个简短的、可重复的示例,显示了对 linregress 的有效调用,然后是失败的调用:

什么可以解释差异,为什么第二个调用不好?

from scipy import stats
import numpy as np

if __name__ == '__main__':
    x = np.random.random(10)
    y = np.random.random(10)
    print(x,y)
    slope, intercept, r_value, p_value, std_err = stats.linregress(x,y)


'''
Code above works
Code below fails
'''

    X = np.asarray([[-15.93675813],
 [-29.15297922],
 [ 36.18954863],
 [ 37.49218733],
 [-48.05882945],
 [ -8.94145794],
 [ 15.30779289],
 [-34.70626581],
 [  1.38915437],
 [-44.38375985],
 [  7.01350208],
 [ 22.76274892]])

    Y = np.asarray( [[  2.13431051],
 [  1.17325668],
 [ 34.35910918],
 [ 36.83795516],
 [  2.80896507],
 [  2.12107248],
 [ 14.71026831],
 [  2.61418439],
 [  3.74017167],
 [  3.73169131],
 [  7.62765885],
 [ 22.7524283 ]])

    print(X,Y) # The array initialization succeeds, if both arrays are print out


    for i in range(1,len(X)):
        slope, intercept, r_value, p_value, std_err = (stats.linregress(X[0:i,:], y = Y[0:i,:]))

【问题讨论】:

  • 你能发布完整的错误信息和堆栈跟踪吗?
  • 你的 X 和 Y 的形状是:(12, 1) 但你需要的是 (12, )。
  • 另外,i 的哪个值会导致问题?
  • 对于同样错误的 pandas 用户:使用df.pop('value')linregression 返回 (R, ) 形状。这将返回文档和此问题中预期的 5 个值 slope, intercept, r_value, p_value, std_err

标签: python scipy linear-regression


【解决方案1】:

您的问题源于对 XY 数组进行切片。你也不需要for 循环。请改用以下内容,它应该可以工作。

slope, intercept, r_value, p_value, std_err = stats.linregress(X[:,0], Y[:,0])

【讨论】:

  • 他们可能仍然想要 for 循环(很难说)。但解决方案[...,:]改为[...,0]
  • 我假设他/她使用了for 循环来处理数组的形状。如果使用正确的切片,则不需要 for 循环。
  • 我以为他们试图获得 n 个不同回归的结果,每个回归都考虑 X/Y 中的一个附加元素。
  • @jedwards 是的,你是对的。我打算得到 n 个不同回归的结果。但是文档表明解决方案是将[...,:]更改为[...,0]呢?
  • @jedwards 来自文档,x, y : array_like 两组测量值。两个数组应该具有相同的长度。如果只给出 x(并且 y=None),那么它必须是一个二维数组,其中一维的长度为 2。然后通过沿长度为 2 的维度拆分数组来找到两组测量值。
【解决方案2】:

问题源于您对np.asarray 的输入是单元素列表的列表。

因此,XY 都具有 (12,1) 的形状:

print(X.shape)  # (12, 1)   [or (12L, 1L), depending on version]
print(Y.shape)  # (12, 1)

请注意,这些都是二维数组。即使其中一个维度是 1,它们仍然被认为是二维的。

现在考虑这种创建数组的方式:

x = np.asarray([1,2,3,4,5])
print(x.shape)  # (5,)

注意,在这种情况下,由于我们将整数列表传递给asarray,因此我们得到了一个一维数组。

当使用两个变量调用您的函数时,每个变量都需要是一维数组。因此,您可以将数组最初创建为一维:

例如,手工:

X = np.asarray([-15.93675813,
                -29.15297922,
                 36.18954863,
                 37.49218733,
                -48.05882945,
                 -8.94145794,
                 15.30779289,
                -34.70626581,
                  1.38915437,
                -44.38375985,
                  7.01350208,
                 22.76274892])

或者通过列表理解:

y_data = [[  2.13431051],
          [  1.17325668],
          [ 34.35910918],
          [ 36.83795516],
          [  2.80896507],
          [  2.12107248],
          [ 14.71026831],
          [  2.61418439],
          [  3.74017167],
          [  3.73169131],
          [  7.62765885],
          [ 22.7524283 ]]
Y = np.asarray([e[0] for e in y_data])

或者通过切片:

Y = np.asarray([[  2.13431051],
                [  1.17325668],
                [ 34.35910918],
                [ 36.83795516],
                [  2.80896507],
                [  2.12107248],
                [ 14.71026831],
                [  2.61418439],
                [  3.74017167],
                [  3.73169131],
                [  7.62765885],
                [ 22.7524283 ]])
Y = Y[:,0]

所有三种方法都将导致您拥有形状为(12,)(一维)的XY

print(X.shape)  # (12,)
print(Y.shape)  # (12,)

然后,您可以将循环用作:

for i in range(3,len(X)):
    slope, intercept, r_value, p_value, std_err = stats.linregress(X[0:i], y = Y[0:i])
    print(slope)

注意,我从 3 开始循环,这是“有意义”的第一个值。

或者,你可以保持你的数组不被修改为二维,并且只在你的循环中修复切片语法:

for i in range(3,len(X)):
    slope, intercept, r_value, p_value, std_err = stats.linregress(X[0:i,0], y = Y[0:i,0])
    print(slope)

这是我评论的答案中建议的方法。

【讨论】:

    【解决方案3】:

    经过几次尝试,以下对我有用:

    slope, intercept, r_value, p_value, std_err = stats.linregress(X[:], Y[:])
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-19
      • 1970-01-01
      • 1970-01-01
      • 2020-01-20
      • 2015-09-04
      • 2017-11-25
      相关资源
      最近更新 更多