#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.