Как объединить векторы столбцов в матрицу - PullRequest
1 голос
/ 02 марта 2020

Как объединить несколько векторов столбцов в матрицу? Например, если у меня есть 3 10 x 1 векторов, как мне поместить их в матрицу 10 x 3? Вот что я пробовал до сих пор:

D0 =np.array([[np.cos(2*np.pi*f*time)],[np.sin(2*np.pi*f*time)],np.ones((len(time),1)).transpose()],'float').transpose()

это дает мне что-то вроде этого,

[[[ 1.00000000e+00  0.00000000e+00  1.00000000e+00]]

 [[ 9.99999741e-01  7.19053432e-04  1.00000000e+00]]

 [[ 9.99998966e-01  1.43810649e-03  1.00000000e+00]]

 ...

 [[ 9.99998966e-01 -1.43810649e-03  1.00000000e+00]]

 [[ 9.99999741e-01 -7.19053432e-04  1.00000000e+00]]

 [[ 1.00000000e+00 -2.15587355e-14  1.00000000e+00]]]

, но я не думаю, что это правильно, это больше похоже на массив списков (и я не мог сделать матричное умножение с этой формой) ... Я также пытался numpy .concatenate, но у меня это тоже не сработало ... Глядя в стек дальше ....

В нотации Matlab мне нужно привести это в форму

D0 =[cos(2*pi*f *t1), sin(2*pi*f*t1) ,1; cos(2*pi*f*t2), sin(2*pi*f*t2) ,1;....] etc

, чтобы я мог найти решение наименьших квадратов s_hat:

s_hat = (D0^T D0)^-1(D0^T x)

, где x - другое входной вектор, содержащий образцы синусоиды, которую я пытаюсь подогнать.

В Matlab я мог бы просто набрать

D0 = [cos(2*np.pi*f*time),sin(2*np.pi*f*time), repmat(1,len(time),1)]

, чтобы создать матрицу D0. Как мне сделать это в python?

Спасибо!

Ответы [ 2 ]

3 голосов
/ 02 марта 2020

Здесь у вас есть эквивалентные полные примеры в Matlab и Python / NumPy:

% Matlab
f = 0.1;
time = [0; 1; 2; 3];
D0 = [cos(2*pi*f*time), sin(2*pi*f*time), repmat(1,length(time),1)]
# Python
import numpy as np
f = 0.1
time = np.array([0, 1, 2, 3])
D0 = np.array([np.cos(2*np.pi*f*time), np.sin(2*np.pi*f*time), np.ones(time.size)]).T
print(D0)

Обратите внимание, что в отличие от Matlab, Python / NumPy не имеет специального синтаксиса для различения guish строк из столбцов (, против ; в Matlab). Точно так же массив 1D NumPy не имеет понятия, является ли он вектором «столбца» или «строки». При объединении нескольких массивов 1D NumPy в один двумерный массив, как указано выше, каждый одномерный массив заканчивается как строка в двумерном массиве. Поскольку вы хотите, чтобы они были столбцами, вам нужно транспонировать 2D-массив, который здесь выполняется просто атрибутом .T.

1 голос
/ 02 марта 2020

Если массивы действительно имеют (10,1) форму, то просто объедините:

In [60]: x,y,z = np.ones((10,1),int), np.zeros((10,1),int), np.arange(10)[:,None]              
In [61]: np.concatenate([x,y,z], axis=1)                                                       
Out[61]: 
array([[1, 0, 0],
       [1, 0, 1],
       [1, 0, 2],
       [1, 0, 3],
       [1, 0, 4],
       [1, 0, 5],
       [1, 0, 6],
       [1, 0, 7],
       [1, 0, 8],
       [1, 0, 9]])

Если они на самом деле 1d, вам придется так или иначе манипулировать размерами. Например, измените форму или добавьте измерение, как я сделал с z выше. Или используйте некоторую функцию, которая сделает это за вас:

In [62]: x,y,z = np.ones((10,),int), np.zeros((10,),int), np.arange(10)                        
In [63]: z.shape                                                                               
Out[63]: (10,)
In [64]: np.array([x,y,z]).shape                                                               
Out[64]: (3, 10)
In [65]: np.array([x,y,z]).T       # transpose                                                            
Out[65]: 
array([[1, 0, 0],
       [1, 0, 1],
       [1, 0, 2],
       [1, 0, 3],
       [1, 0, 4],
       [1, 0, 5],
       [1, 0, 6],
       [1, 0, 7],
       [1, 0, 8],
       [1, 0, 9]])

np.array([...]) объединяет массивы в новом начальном измерении. Помните, что в Python / numpy первое измерение является самым внешним (MATLAB наоборот).

stack варианты настраивают размеры, а затем делают concatenate:

In [66]: np.stack([x,y,z],axis=1).shape                                                        
Out[66]: (10, 3)
In [67]: np.column_stack([x,y,z]).shape                                                        
Out[67]: (10, 3)
In [68]: np.vstack([x,y,z]).shape                                                              
Out[68]: (3, 10)

===

D0 =np.array([[np.cos(2*np.pi*f*time)],[np.sin(2*np.pi*f*time)],np.ones((len(time),1)).transpose()],'float').transpose()

Полагаю, f - это скаляр, а time - это массив 1d (shape (10,))

[np.cos(2*np.pi*f*time)]

, оборачивает (10,) в [], который при превращении в массив принимает форму (1,10).

np.ones((len(time),1)).transpose() транспонируется (10,1) в (1,10).

np.array(....) из них создает массив (3,1,10). Транспонирование это (10,1,3).

Если вы уронили [] и сформировали (1,10) массивы:

D0 =np.array([np.cos(2*np.pi*f*time), np.sin(2*np.pi*f*time), np.ones((len(time))]).transpose()

объединятся 3 (10, ) для создания (3,10) массивов, который затем транспонируется в (10,3).

В качестве альтернативы

D0 =np.concatenate([[np.cos(2*np.pi*f*time)], [np.sin(2*np.pi*f*time)], np.ones((1,len(time),1))], axis=0)

объединяет 3 (1,10) массива для создания ( 3,10), который вы можете перенести.

...