как добавить матрицу numpy в пустой массив numpy

#python #arrays #numpy #matrix #append

#python #массивы #numpy #матрица #добавить

Вопрос:

Я хочу добавить numpy массив (матрицу) в массив с помощью цикла

 data=[[2 2 2] [3 3 3]]
Weights=[[4 4 4] [4 4 4] [4 4 4]]
All=np.array([])  
for i in data:
    #i=[2 2 2 ]  #for example
    h=i*Weights         
    #h=[[8 8 8][8 8 8][8 8 8]] 
    All=np.concatenate((All,h),axis=0)                
  

Я получаю эту ошибку:

 ValueError: all the input arrays must have same number of dimensions
  

Я хочу, чтобы переменная «All» была

 [[8 8 8][8 8 8][8 8 8] [12 12 12][12 12 12][12 12 12]]
  

Есть какой-нибудь способ, как я могу добавить «h» ко «Всем» через цикл?

Ответ №1:

Вариант 1: Измените размер вашего исходного All массива на 3 столбца, чтобы количество столбцов совпадало h :

 All=np.array([]).reshape((0,3))

for i in data:
    h=i*Weights      
    All=np.concatenate((All,h))

All
#array([[  8.,   8.,   8.],
#       [  8.,   8.,   8.],
#       [  8.,   8.,   8.],
#       [ 12.,  12.,  12.],
#       [ 12.,  12.,  12.],
#       [ 12.,  12.,  12.]])
  

Вариант 2:
Используйте оператор if-else для обработки начального случая пустого массива:

 All=np.array([])
for i in data:
    h=i*Weights      
    if len(All) == 0:
        All = h
    else:
        All=np.concatenate((All,h))

All
#array([[ 8,  8,  8],
#       [ 8,  8,  8],
#       [ 8,  8,  8],
#       [12, 12, 12],
#       [12, 12, 12],
#       [12, 12, 12]])
  

Вариант 3:
Используйте itertools.product() :

 import itertools
np.array([i*j for i,j in itertools.product(data, Weights)])

#array([[ 8,  8,  8],
#       [ 8,  8,  8],
#       [ 8,  8,  8],
#       [12, 12, 12],
#       [12, 12, 12],
#       [12, 12, 12]])
  

Комментарии:

1. Я попробовал второй вариант, он отлично сработал и достиг цели.

2. Я бы сказал, что попробовал третий вариант, но у меня он не очень хорошо сработал

3. Интересно. Возможно, ваши данные сложнее, чем то, что вы показали, для меня это дает желаемый результат как в python 2, так и в python 3.

4. Это правда, мои данные более сложные. Я попытался упростить это в вопросе

Ответ №2:

Адам, как насчет простого использования пары вложенных циклов? Я верю, что этот код будет делать то, что вы хотите.

 import numpy as np
data = ([2,2,2],[3,3,3])
weights = ([4,4,4],[4,4,4],[4,4,4])

output=np.array([])
for each_array in data:
    for weight in weights:
            each_multiplication = np.multiply(each_array, weight)
            output = np.append(output,each_multiplication)

print output
  

np.multiply() выполняет поэлементное умножение вместо матричного. Насколько я могу понять из вашего примера ввода и вывода, это то, чего вы пытаетесь достичь.

Ответ №3:

Возможно, это не лучшее решение, но, похоже, оно работает.

 data = np.array([[2, 2, 2], [3, 3, 3]])
Weights = np.array([[4, 4, 4], [4, 4, 4], [4, 4, 4]])
All = []

for i in data:
    for j in Weights:
        h = i * j
        All.append(h)

All = np.array(All)
  

Я хотел бы сказать, что это не лучшее решение, потому что оно добавляет результат в список и в конце преобразует список в массив numpy, но оно хорошо работает для небольших приложений. Я имею в виду, что если вам нужно выполнять подобные сложные вычисления, я бы подумал о поиске другого метода. В любом случае, с помощью этого метода вам не нужно думать о преобразованиях чисел с плавающей запятой. Надеюсь, это поможет.

Комментарии:

1. Это широко используемый способ построения массива, когда необходим цикл.

2. да, я согласен. я имею в виду, что если вам нужно использовать это только для некоторых небольших вычислений, я думаю, что это может сработать хорошо, но это медленнее, чем просто использовать numpy, и, конечно, добавления к массиву на каждой итерации следует избегать, если массив длинный.

Ответ №4:

Предпочтительный способ построения массива с помощью цикла — собирать значения в списке и выполнять concatenate один раз в конце:

 In [1025]: data
Out[1025]: 
array([[2, 2, 2],
       [3, 3, 3]])
In [1026]: Weights
Out[1026]: 
array([[4, 4, 4],
       [4, 4, 4],
       [4, 4, 4]])
  

Добавление в список выполняется намного быстрее, чем повторное concatenate ; плюс это позволяет избежать проблемы с формой «пустого` массива:

 In [1027]: alist=[]
In [1028]: for row in data:
      ...:     alist.append(row*Weights)
In [1029]: alist
Out[1029]: 
[array([[8, 8, 8],
        [8, 8, 8],
        [8, 8, 8]]), array([[12, 12, 12],
        [12, 12, 12],
        [12, 12, 12]])]

In [1031]: np.concatenate(alist,axis=0)
Out[1031]: 
array([[ 8,  8,  8],
       [ 8,  8,  8],
       [ 8,  8,  8],
       [12, 12, 12],
       [12, 12, 12],
       [12, 12, 12]])
  

Вы также можете объединить массивы в новом измерении с помощью np.array или np.stack :

 In [1032]: np.array(alist)
Out[1032]: 
array([[[ 8,  8,  8],
        [ 8,  8,  8],
        [ 8,  8,  8]],

       [[12, 12, 12],
        [12, 12, 12],
        [12, 12, 12]]])
In [1033]: _.shape
Out[1033]: (2, 3, 3)
  

Я могу создать эту 3D-версию с помощью простого широковещательного умножения — без циклов

 In [1034]: data[:,None,:]*Weights[None,:,:]
Out[1034]: 
array([[[ 8,  8,  8],
        [ 8,  8,  8],
        [ 8,  8,  8]],

       [[12, 12, 12],
        [12, 12, 12],
        [12, 12, 12]]])
  

Добавьте .reshape(-1,3) к этому, чтобы получить версию (6,3).

np.repeat(data,3,axis=0)*np.tile(Weights,[2,1]) также создает желаемый массив 6×3.