如何堆叠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
工作正常,但沿错误的维度连接。
简短的回答:你不能。NumPy 本身不支持锯齿状数组。
长答案:
>>> a = ones((3,))
>>> b = ones((2,))
>>> c = array([a, b])
>>> c
array([[ 1. 1. 1.], [ 1. 1.]], dtype=object)
给出一个可能会或可能不会像您期望的那样运行的数组。例如,它不支持sum
or之类的基本方法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
也可能很有趣。)
通常,将不同长度的数组放在一起存在歧义,因为数据的对齐可能很重要。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]])
有一个用于有效处理此类数组的新库:https ://github.com/scikit-hep/awkward-array
如果您确实想使用 NumPy,您可以将形状与 np.nan 匹配,然后稍后“解包” nan 填充的数组。这是一个带有函数的示例。
import numpy as np
from numpy import *
a = np.array([[3,3,3]]).astype(float)
b = np.array([[2,2]]).astype(float)
# Extend each vector in array with Nan to reach same shape
def Pack_Matrices_with_NaN(List_of_matrices, Matrix_size):
Matrix_with_nan = np.arange(Matrix_size)
for array in List_of_matrices:
start_position = len(array[0])
for x in range(start_position,Matrix_size):
array = np.insert(array, (x), np.nan, axis=1)
Matrix_with_nan = np.vstack([Matrix_with_nan, array])
Matrix_with_nan = Matrix_with_nan[1:]
return Matrix_with_nan
arrays = [a,b]
packed_matrices = Pack_Matrices_with_NaN(arrays, 5)
print(packed_matrices)
Output:
[[ 3. 3. 3. nan nan]
[ 2. 2. nan nan nan]]
但是,最简单的方法是将数组附加到列表中:
import numpy as np
a = np.array([3,3,3])
b = np.array([2,2])
c = []
c.append(a)
c.append(b)
print(c)
Output:
[array([3, 3, 3]), array([2, 2])]
我知道这是一个非常古老的帖子,并且可能有更好的方法来做到这一点,但为什么不直接使用 append 进行这样的操作:
import numpy as np
a = np.ones((3,))
b = np.ones((2,))
c = np.append(a, b)
print(c)
输出:
[1. 1. 1. 1. 1.]
我使用以下代码将不同长度的列表组合在一个 numpy 数组中,并将长度信息保存在第二个数组中:
import numpy as np
# create an example list (number can be increased):
my_list=[np.ones(i) for i in np.arange(1000)]
# measure and store length and find max:
dlc=np.array([len(i) for i in my_list]) #list contains the data length code
max_length=max(dlc)
# now we allocate an empty array
result=np.empty(max_length*len(my_list)).reshape(len(my_list),max_length)
# populate:
for i in np.arange(len(dlc)):
result[i][np.arange(dlc[i])]=my_list[i]
# check how the 10th element looks like
print(result[10],dlc[10])
我确信在循环的情况下可以改进代码。但它已经很快工作了,因为内存是由空数组预先分配的。