`scipy.stats.linregress`出现“ValueError: too many values to unpack (expected 4)”错误提示

6
我知道这个错误信息(ValueError: too many values to unpack (expected 4))出现在函数返回的变量值多于设置的变量值时。根据scipy文档 (http://docs.scipy.org/doc/scipy/reference/generated/scipy.stats.linregress.html),scipy.stats.linregress返回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,:]))

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

9

你遇到的问题源于对XY数组进行切片。另外,你不需要使用for循环。使用以下代码替代即可。

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

1
他们可能仍然希望使用for循环(难以确定),但解决方案[...,:]更改为[...,0] - jedwards
我假设他/她已经使用了for循环来处理数组的形状。如果使用正确的切片,就不需要for循环了。 - Dataman
我以为他们试图获得n个不同回归的结果,每个回归都考虑了X/Y中的一个附加元素。 - jedwards
@jedwards 是的,你说得对。我的意图是获取n个不同回归的结果。然而,文档中什么地方表明解决方案是将 [...,:] 更改为 [...,0] - Muno
@jedwards 从文档中得知,x、y:array_like 两组测量数据。两个数组的长度应该相同。如果只提供了x(而y=None),那么它必须是一个二维数组,其中一个维度的长度为2。然后通过沿着长度为2的维度分割数组来找到两组测量数据。 - Muno
@Muno,因为你正在使用列表创建数组,其中每个元素本身都是一个列表。这将导致XY成为二维数组,每个数组的.shape = (12,1)。但是函数不期望二维数组,它期望一维数组(例如.shape = (12,))。因此,您需要使用[...,0]提取单个列。当您使用[...,:]时,您正在提取所有列,因此输入仍然是每个二维(12,1)数组。 - jedwards

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)

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

0

经过几次尝试,以下方法对我有效:

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接