2015-10-28 6 views
0

У меня есть следующая проблема: у меня есть массив numpy, у которого есть пустые массивы numpy в качестве элементов, а его форма 2x2, но имеет смысл как 2,2,0, что имеет смысл. Проблема заключается в том, что при попытке добавить значения к любому из пустых массивов numpy ничего не происходит.Добавить значения в массив numpy пустых массивов numpy

MWE:

import numpy as np 

a = np.array([[],[],[],[]]) 
a = np.reshape(a, (2,2,0)) 

a[0][0] = np.append(a[0][0], 1) 
a[0][1] = np.append(a[0][0], [1]) 

Output: 
>>>a[0][0] 
array([], dtype=float64) 
>>>a[0][1] 
array([], dtype=float64) 

Это означает, что ничего не происходит. Как я могу добавить значения в мой массив 2x2 numpy по одному?

ответ

0

После некоторого времени я понял, что ответ очевиден.

Когда вы пытаетесь добавить один элемент в любой из 4 пустых массивов numpy, вы по существу разбиваете массив 2,2,0, и так или иначе модуль numpy предотвращает это.

Если вы хотите добавить элементы по одному, вам придется добавить их во временный 1D-массив в группах по 4, а затем изменить временный массив на форму (2,2,1), а затем добавить полный временный массив 2x2 numpy на пустой, по существу, идущий от формы 2,2,0 до 2,2,1 формы.

Повторите столько раз, сколько необходимо. MWE:

import numpy as np 

a = np.array([[],[],[],[]]) 
a = np.reshape(a, (2,2,0)) 
temporary = np.array([]) 
for i in range(4): 
    temporary = np.append(temporary, i) 
temporary = np.reshape(temporary, (2,2,1)) 
a = np.append(a, temporary) 
a = np.reshape(a, (2,2,1)) 
a = np.append(a, temporary) 
a = np.reshape(a, (2,2,2)) 

И тогда вы можете получить доступ к элементам, как а [0] [0] [0] а [0] [0] [1]

Sth странно, что когда ты является добавление временного массива к нему автоматически перестраивает ее формы (4,)

+0

Хотя этот вид работ, что-нибудь на основе добавления к NumPy массивов будет очень неэффективно, так как NumPy не предназначен для этого и не использует стратегию роста, что бы сделать что эффективным. Возможно, вам захочется рассмотреть списки для частей вашего кода, где ваши структуры данных должны динамически развиваться или найти способ переназначить ваш массив, а затем заполнить его вместо использования 'append'. – user2357112

+0

Полностью согласен, в основном мне просто нужны внутренние данные, чтобы быть массивом numpy, я просто играл с ним, и это показалось мне странным, а затем продолжило выяснять, как я смогу это сделать. – Satrapes

+0

'np.append' docs говорит, что он работает с сплющенными массивами (1d), если вы не указали ось, а значит, форму' (4,) '. Поверхностное сходство с списком append обманчиво. – hpaulj

0

a = np.array([[],[],[],[]]) делает

array([], shape=(4, 0), dtype=float64) 

Это массив из 0 элемента s, который содержит поплавки и имеет форму (4,0). Ваше изменение изменяет форму, но не число элементов - все равно 2 * 2 * 0 = 0.

Это не массив, содержащий другие массивы.

Прикрепление к элементу a производит массив 1 элемент с формой (1,)

In [164]: np.append(a[0,0],1) 
Out[164]: array([ 1.]) 

Попытка назначить его обратно в a[0,0] ничего не делает. На самом деле я бы ожидал ошибки. Но в любом случае он не должен и не может добавить значение к массиву, которое по определению имеет 0 элементов.

Вы должны думать, что вы определили массив 2x2, где каждый элемент может быть объектом, таким как другой массив. Для этого вам нужно создать массив по-разному.

Например:

In [176]: a=np.empty((2,2),dtype=object) 
In [177]: a 
Out[177]: 
array([[None, None], 
     [None, None]], dtype=object) 

In [178]: a.fill([]) # lazy way of replacing the None 
In [179]: a 
Out[179]: 
array([[[], []], 
     [[], []]], dtype=object) 

Now I have a (2,2) array, where each element can be any Python object, though at the moment they all are empty lists. As noted in the comment, by using `fill`, each element is the same empty list; change one (in a mutable way), and you change all). 

Я мог бы использовать np.append, чтобы создать новый массив (хотя я вообще не рекомендую использовать np.append). (но остерегайтесь a[0,0].append(1), операции с списком).

In [180]: a[0,0]=np.append(a[0,0],1)  
In [181]: a 
Out[181]: 
array([[array([ 1.]), []], 
     [[], []]], dtype=object) 

Я мог бы заменить элемент с массива 2х2:

In [182]: a[0,1]=np.array([[1,2],[3,4]]) 

или строку

In [183]: a[1,0]='astring' 

или другой список

In [184]: a[1,1]=[1,2,3] 

In [185]: a 
Out[185]: 
array([[array([ 1.]), array([[1, 2], 
     [3, 4]])], 
     ['astring', [1, 2, 3]]], dtype=object) 

Там реальная разница между этим (2,2) массив объектов d a 3 или 4d массив поплавков, (2,2 ,?).


Вот как я бы выполнить дописывает в своем ответе

создать (2,2,0) массив непосредственно:

In [207]: a=np.zeros((2,2,0)) 

и (2,2,1) просто диапазон реорганизован:

In [208]: temporary =np.arange(4).reshape(2,2,1) 

In [209]: a 
Out[209]: array([], shape=(2, 2, 0), dtype=float64) 

In [210]: temporary 
Out[210]: 
array([[[0], 
     [1]], 

     [[2], 
     [3]]]) 

np.append просто альтернативный передний конец concatenate. Поэтому я буду использовать это с явным контролем над осью. append предназначен для пользователей Python, которые упорствуют в мышлении в терминах списка.

In [211]: np.concatenate([a,temporary],axis=2) 
Out[211]: 
array([[[ 0.], 
     [ 1.]], 

     [[ 2.], 
     [ 3.]]]) 

In [212]: a1=np.concatenate([a,temporary],axis=2) 

In [213]: a2=np.concatenate([a1,temporary],axis=2) 

In [214]: a2 
Out[214]: 
array([[[ 0., 0.], 
     [ 1., 1.]], 

     [[ 2., 2.], 
     [ 3., 3.]]]) 

In [215]: a2.shape 
Out[215]: (2, 2, 2) 
+0

'a.fill ([])' является опасным, поскольку все элементы являются тем же самым списком после завершения. – user2357112

+0

Все, хотя я должен был бы выполнить изменяемые операции с списками в этом элементе списка, чтобы увидеть такую ​​проблему. 'a [0,0] .append (1)' изменит все элементы. Изменения, которые я продемонстрировал, заменяют начальные '[]'. – hpaulj

Смежные вопросы