如何在NumPy中堆叠不同长度的向量?

时间:2013-02-16 23:42:42

标签: python numpy

如何堆叠形状为n的列(x,)向量,其中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 个答案:

答案 0 :(得分:27)

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

答案很长:

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

给出一个可能会或可能不会按预期运行的数组。例如。它不支持像sumreshape这样的基本方法,你应该像对待普通的Python列表[a, b]那样对待它(迭代它来执行操作而不是使用它)矢量化成语。

存在几种可能的解决方法;最简单的方法是将ab强制转换为公共长度,可能使用masked arrays或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也可能很有趣。)

答案 1 :(得分:4)

通常,将不同长度的数组放在一起是不明确的,因为数据的对齐可能很重要。 JSONObject mainObj=new JSONObject(); JSONArray arr=new JSONArray(); for(int i=0;i<Memory.finalOrder.size();i++) { JSONObject jo = new JSONObject(); jo.put("name",Memory.finalOrder.get(i).getName()); jo.put("quantity",Memory.finalOrder.get(i).getQuantity()); jo.put("price",Memory.finalOrder.get(i).getPrice()); arr.put(jo); } mainObj.put("TableName",Memory.tableName); mainObj.put("Data",arr.toString()); 有不同的高级解决方案来解决这个问题,例如将系列合并到dataFrames。

如果您只想从第一个元素开始填充列,我通常会建立一个矩阵并填充列。当然,您需要使用空值填充矩阵中的空白区域(在本例中为Pandas

np.nan

答案 2 :(得分:0)

有一个新的库可以有效处理这种类型的数组:https://github.com/scikit-hep/awkward-array

答案 3 :(得分:0)

我知道这是一篇非常古老的文章,并且可能会有更好的方法,但是为什么不只对此类操作使用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.]

答案 4 :(得分: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])]

答案 5 :(得分:-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])

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