ValueError:所有输入数组必须具有相同的维数
Posted
技术标签:
【中文标题】ValueError:所有输入数组必须具有相同的维数【英文标题】:ValueError: all the input arrays must have same number of dimensions 【发布时间】: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 追加空数组
【参考方案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 所以...正如我所说,使用 append
与 stack
与 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)
.以上是关于ValueError:所有输入数组必须具有相同的维数的主要内容,如果未能解决你的问题,请参考以下文章
Numpy hstack - “ValueError:所有输入数组必须具有相同的维数” - 但它们确实如此
ValueError:目标和输入必须具有相同数量的元素。目标 nelement (50) != 输入 nelement (100)