Подтвердить что ты не робот

Как стекировать векторы разной длины в 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 работает отлично, но конкатенации по неправильному размеру.

4b9b3361

Ответ 1

Короткий ответ: вы не можете. 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 также может быть интересным.)

Ответ 2

В общем, существует двусмысленность в объединении массивов разной длины, поскольку выравнивание данных может иметь значение. Pandas имеет различные расширенные решения для решения этой проблемы, например. для объединения рядов в dataFrames.

Если вы хотите просто заполнить столбцы, начиная с первого элемента, то, что я обычно делаю, это построить матрицу и заполнить столбцы. Конечно, вам нужно заполнить пустые пространства в матрице нулевым значением (в данном случае 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]])