37

如何堆叠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工作正常,但沿错误的维度连接。

4

6 回答 6

40

简短的回答:你不能。NumPy 本身不支持锯齿状数组。

长答案:

>>> a = ones((3,))
>>> b = ones((2,))
>>> c = array([a, b])
>>> c
array([[ 1.  1.  1.], [ 1.  1.]], dtype=object)

给出一个可能会或可能不会像您期望的那样运行的数组。例如,它不支持sumor之类的基本方法reshape,您应该像对待普通 Python 列表一样对待[a, b]它(迭代它以执行操作,而不是使用矢量化习语)。

存在几种可能的解决方法;最简单的方法是强制ab达到一个共同的长度,可能使用掩码数组或 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也可能很有趣。)

于 2013-02-16T23:48:15.813 回答
6

通常,将不同长度的数组放在一起存在歧义,因为数据的对齐可能很重要。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]])
于 2016-07-28T18:08:13.193 回答
0

有一个用于有效处理此类数组的新库:https ://github.com/scikit-hep/awkward-array

于 2019-10-29T19:40:06.917 回答
0

如果您确实想使用 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])]
于 2021-07-09T01:55:23.713 回答
-1

我知道这是一个非常古老的帖子,并且可能有更好的方法来做到这一点,但为什么不直接使用 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.]
于 2019-11-08T17:13:31.173 回答
-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])

我确信在循环的情况下可以改进代码。但它已经很快工作了,因为内存是由空数组预先分配的。

于 2021-03-30T06:36:39.960 回答