2016-07-20 4 views
1

У меня есть массив Numpy формы (5,5,3,2). Я хочу взять элемент (1,4) этой матрицы, который также является матрицей формы (3,2), и добавить к нему элемент - так он становится массивом (4,2). код я использую следующее:Добавить массив numpy в элемент

import numpy as np 
a = np.random.rand(5,5,3,2) 
a = np.array(a, dtype = object) #So I can have different size sub-matrices 
a[2][3] = np.append(a[2][3],[[1.0,1.0]],axis=0) #a[2][3] shape = (3,2) 

Я всегда получить ошибку:

ValueError: could not broadcast input array from shape (4,2) into shape (3,2) 

Я понимаю, что форма возвращается функцией np.append не то же самое, как a[2][3] sub-array, но я думал, что dtype=object решит мою проблему. Однако мне нужно это сделать. Есть ли способ обойти это ограничение? Я также пытался использовать функцию insert, но я не знаю, как добавить элемент в нужное место.

+0

Это имеет смысл, если вы измените * каждый элемент '' 3 x 2' на '4 x 2', другие мудрые размеры не будут работать. – gobrewers14

ответ

1

Удостоверьтесь, что вы понимаете, что вы произвели. Это требует проверки формы и DTYPE, и, возможно, глядя на значения

In [29]: a = np.random.rand(5,5,3,2) 
In [30]: b=np.array(a, dtype=object) 
In [31]: a.shape 
Out[31]: (5, 5, 3, 2)  # a is a 4d array 
In [32]: a.dtype 
Out[32]: dtype('float64') 
In [33]: b.shape 
Out[33]: (5, 5, 3, 2)  # so is b 
In [34]: b.dtype 
Out[34]: dtype('O') 
In [35]: b[2,3].shape 
Out[35]: (3, 2) 

In [36]: c=np.append(b[2,3],[[1,1]],axis=0) 
In [37]: c.shape 
Out[37]: (4, 2) 
In [38]: c.dtype 
Out[38]: dtype('O') 

b[2][3] также является массивом. b[2,3] - это правильный нулевой способ индексирования 2 измерений.

Я подозреваю, что вы хотели b быть (5,5) массив, содержащий массивы (как объекты), и вы думаете, что вы можете просто заменить один из тех, с (4,2) массива. Но конструктор b просто меняет floatsa на объекты, без изменения формы (или 4-й натуры) b.

Я мог бы построить массив объектов (5,5) и заполнить его значениями от a. А потом заменить одно из этих значений с (4,2) массива:

In [39]: B=np.empty((5,5),dtype=object) 
In [40]: for i in range(5): 
    ...:  for j in range(5): 
    ...:   B[i,j]=a[i,j,:,:] 
    ...:   
In [41]: B.shape 
Out[41]: (5, 5) 
In [42]: B.dtype 
Out[42]: dtype('O') 
In [43]: B[2,3] 
Out[43]: 
array([[ 0.03827568, 0.63411023], 
     [ 0.28938383, 0.7951006 ], 
     [ 0.12217603, 0.304537 ]]) 
In [44]: B[2,3]=c 
In [46]: B[2,3].shape 
Out[46]: (4, 2) 

Этот конструктор для B немного сырой. Я ответил на другие вопросы о создании/заполнении массивов объектов, но я не собираюсь тратить время на оптимизацию этого случая.Это только для иллюстрации.

0

Проблема в том, что вы пытаетесь назначить [2] [3] Вместо этого создайте новый массив.

new_array = np.append(a[2][3],np.array([[1.0,1.0]]),axis=0) 
+0

Но если я это сделаю, 'a' не изменится. Мне нужно обновить эту таблицу новыми значениями. Создание нового массива бесполезно. – VictorSeven

+0

@V_Programmer oh в этом случае вам нужно изменить каждый элемент. а не [2] [3], но также [n [n]. Чтобы сохранить форму, это будет (5,5,2,4) – EL3PHANTEN

+0

, можете ли вы отредактировать свой ответ, чтобы добавить пример, пожалуйста? – VictorSeven

1

В массиве object, любой элемент может быть на самом деле массив (или любой другой тип объекта).

import numpy as np 
a = np.random.rand(5,5,3,2) 
a = np.array(a, dtype=object) 

# Assign an 1D array to the array element ``a[2][3][0][0]``: 
a[2][3][0][0] = np.arange(10) 
a[2][3][0][0][9] # 9 

Однако a[2][3] не является элементом массива, это целый массив.

a[2][3].ndim # 2 

Поэтому, когда вы делаете a[2][3] = (something) вы используете broadcasting вместо назначения элемента: NumPy пытается заменить содержимое подмассива a[2][3] и не из-за несоответствия формы. Макет памяти массивов numpy не позволяет изменять форму подмассивов.

Редактировать: Вместо использования массивов numpy вы можете использовать вложенные списки. Эти вложенные списки могут иметь произвольные размеры. Обратите внимание, что память выше и что время доступа выше по сравнению с массивом numpy.

import numpy as np 
a = np.random.rand(5,5,3,2) 
a = np.array(a, dtype=object) 
b = np.append(a[2][3], [[1.0,1.0]],axis=0) 
a_list = a.tolist() 
a_list[2][3] = b.tolist() 
+0

Итак, нет способа сделать это ...? Нет трюков или обходных решений? – VictorSeven

+0

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