【问题标题】:ValueError: all the input arrays must have same number of dimensionsValueError:所有输入数组必须具有相同的维数
【发布时间】:2016-12-15 09:11:19
【问题描述】:

np.append 有问题。

我正在尝试使用以下代码复制 20x361 矩阵 n_list_converted 的最后一列:

n_last = []
n_last = n_list_converted[:, -1]
n_lists = np.append(n_list_converted, n_last, axis=1)

但我得到错误:

ValueError:所有输入数组的维数必须相同

但是,我已经通过以下方式检查了矩阵尺寸

 print(n_last.shape, type(n_last), n_list_converted.shape, type(n_list_converted))

我得到了

(20L,) (20L, 361L)

所以尺寸匹配?哪里错了?

【问题讨论】:

  • 试试np.column_stack
  • 成功了!但为什么呢?
  • 尝试使用 axis=None 追加空数组

标签: python arrays numpy append


【解决方案1】:

(n,) 和 (n,1) 不是同一个形状。尝试使用 [:, None] 表示法将向量转换为数组:

n_lists = np.append(n_list_converted, n_last[:, None], axis=1)

或者,在提取n_last 时,您可以使用

n_last = n_list_converted[:, -1:]

获取(20, 1) 数组。

【讨论】:

    【解决方案2】:

    您得到错误的原因是“1 x n”矩阵与长度为 n 的数组不同。

    我建议改用hstack()vstack()。 像这样:

    import numpy as np
    a = np.arange(32).reshape(4,8) # 4 rows 8 columns matrix.
    b = a[:,-1:]                    # last column of that matrix.
    
    result = np.hstack((a,b))       # stack them horizontally like this:
    #array([[ 0,  1,  2,  3,  4,  5,  6,  7,  7],
    #       [ 8,  9, 10, 11, 12, 13, 14, 15, 15],
    #       [16, 17, 18, 19, 20, 21, 22, 23, 23],
    #       [24, 25, 26, 27, 28, 29, 30, 31, 31]])
    

    请注意重复的“7、15、23、31”列。 另外,请注意我使用了a[:,-1:] 而不是a[:,-1]。我的版本生成一列:

    array([[7],
           [15],
           [23],
           [31]])
    

    而不是一行array([7,15,23,31])


    编辑:append()要慢得多。阅读this answer

    【讨论】:

    • np.append 比列表.append 慢;但与stacks 相当。它使用np.concatenate
    • @hpaulj 所以...正如我所说,使用 appendstack 与 2 个矩阵相同,stack 更适合 2 个以上的元素,所以 stack 总是至少和 append一样好。
    【解决方案3】:

    如果我从一个 3x4 数组开始,然后将一个 3x1 数组与轴 1 连接起来,我将得到一个 3x5 数组:

    In [911]: x = np.arange(12).reshape(3,4)
    In [912]: np.concatenate([x,x[:,-1:]], axis=1)
    Out[912]: 
    array([[ 0,  1,  2,  3,  3],
           [ 4,  5,  6,  7,  7],
           [ 8,  9, 10, 11, 11]])
    In [913]: x.shape,x[:,-1:].shape
    Out[913]: ((3, 4), (3, 1))
    

    请注意,要连接的两个输入都有 2 个维度。

    省略:x[:,-1] 是 (3,) 形状 - 它是 1d,因此错误:

    In [914]: np.concatenate([x,x[:,-1]], axis=1)
    ...
    ValueError: all the input arrays must have same number of dimensions
    

    np.append 的代码是(在这种情况下指定了轴)

    return concatenate((arr, values), axis=axis)
    

    所以只要稍微改变语法append 就可以了。它需要 2 个参数,而不是一个列表。它模仿列表append 是语法,但不应与该列表方法混淆。

    In [916]: np.append(x, x[:,-1:], axis=1)
    Out[916]: 
    array([[ 0,  1,  2,  3,  3],
           [ 4,  5,  6,  7,  7],
           [ 8,  9, 10, 11, 11]])
    

    np.hstack 首先确保所有输入都是atleast_1d,然后进行连接:

    return np.concatenate([np.atleast_1d(a) for a in arrs], 1)
    

    所以它需要相同的x[:,-1:] 输入。基本相同的操作。

    np.column_stack 也在轴 1 上进行连接。但首先它通过 1d 输入

    array(arr, copy=False, subok=True, ndmin=2).T
    

    这是将 (3,) 数组转换为 (3,1) 数组的一般方法。

    In [922]: np.array(x[:,-1], copy=False, subok=True, ndmin=2).T
    Out[922]: 
    array([[ 3],
           [ 7],
           [11]])
    In [923]: np.column_stack([x,x[:,-1]])
    Out[923]: 
    array([[ 0,  1,  2,  3,  3],
           [ 4,  5,  6,  7,  7],
           [ 8,  9, 10, 11, 11]])
    

    所有这些“堆栈”都很方便,但从长远来看,了解尺寸和基础np.concatenate 很重要。还知道如何查找此类函数的代码。我经常使用ipython ?? 魔法。

    在时间测试中,np.concatenate 明显更快 - 对于这样的小数组,额外的函数调用层会产生很大的时间差异。

    【讨论】:

      【解决方案4】:

      您还可以通过将 (n,) 括在括号 [ ] 中将 (n,) 转换为 (n,1)。

      例如而不是np.append(b,a,axis=0) 使用np.append(b,[a],axis=0)

      a=[1,2]
      b=[[5,6],[7,8]]
      np.append(b,[a],axis=0)
      

      返回

      array([[5, 6],
             [7, 8],
             [1, 2]])
      

      【讨论】:

      • 反之亦然:b=[1,2]; a=[[5,6],[7,8]]; np.append([b],a,axis=0).
      猜你喜欢
      • 1970-01-01
      • 2019-09-22
      • 2018-06-12
      • 2017-06-18
      • 2018-05-18
      • 2018-06-23
      • 1970-01-01
      • 2017-07-13
      • 1970-01-01
      相关资源
      最近更新 更多