如何在NumPy中堆叠不同长度的向量?
我该如何把形状为 (x,)
的 n
个向量按列叠加在一起,其中 x
可以是任何数字呢?
举个例子,
from numpy import *
a = ones((3,))
b = ones((2,))
c = vstack((a,b)) # <-- gives an error
c = vstack((a[:,newaxis],b[:,newaxis])) #<-- also gives an error
hstack
可以正常工作,但它是在错误的维度上进行连接。
6 个回答
1
有一个新的库可以更高效地处理这种类型的数组:https://github.com/scikit-hep/awkward-array
7
一般来说,把不同长度的数组放在一起会有点模糊,因为数据的对齐可能很重要。Pandas
提供了不同的高级解决方案来处理这个问题,比如把多个系列合并成数据框。
如果你只是想从第一个元素开始填充列,我通常会先构建一个矩阵,然后再填充列。当然,你需要用空值(在这个例子中是 np.nan
)来填充矩阵中的空白部分。
a = ones((3,))
b = ones((2,))
arraylist=[a,b]
outarr=np.ones((np.max([len(ps) for ps in arraylist]),len(arraylist)))*np.nan #define empty array
for i,c in enumerate(arraylist): #populate columns
outarr[:len(c),i]=c
In [108]: outarr
Out[108]:
array([[ 1., 1.],
[ 1., 1.],
[ 1., nan]])
43
简短的回答是:你不能这样做。NumPy 本身不支持不规则数组。
详细的回答:
>>> a = ones((3,))
>>> b = ones((2,))
>>> c = array([a, b])
>>> c
array([[ 1. 1. 1.], [ 1. 1.]], dtype=object)
这样做会得到一个数组,它的表现可能和你预期的不一样。例如,它不支持一些基本的方法,比如 sum
(求和)或 reshape
(重塑),你应该把它当作普通的 Python 列表 [a, b]
来处理(也就是说,遍历它来进行操作,而不是使用向量化的写法)。
有几种可能的解决方法;最简单的办法是把 a
和 b
强制调整为相同的长度,可能可以使用 掩码数组 或者 NaN 来表示某些行中的某些索引是无效的。例如,这里是 b
作为一个掩码数组:
>>> ma.array(np.resize(b, a.shape[0]), mask=[False, False, True])
masked_array(data = [1.0 1.0 --],
mask = [False False True],
fill_value = 1e+20)
这样可以和 a
进行堆叠,如下所示:
>>> ma.vstack([a, ma.array(np.resize(b, a.shape[0]), mask=[False, False, True])])
masked_array(data =
[[1.0 1.0 1.0]
[1.0 1.0 --]],
mask =
[[False False False]
[False False True]],
fill_value = 1e+20)
(对于某些用途,scipy.sparse
也可能会很有趣。)