简体   繁体   中英

Append values to numpy array of empty numpy arrays

I have the following problem, I have an numpy array that has empty numpy arrays as elements and its shape is 2x2 but is reported as 2,2,0 actually which makes sense. The problem is when you try to append values to any of the empty numpy arrays nothing happens.

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)

Which means that nothing happens. How can I append values to my 2x2 numpy array one at a time?

After tinkering for a while I realized that the answer is obvious.

When you are trying to add one element on any of the 4 empty numpy arrays you are essentially breaking the 2,2,0 array and somehow the numpy module prevents you from doing so.

If you would like to add the elements one at a time you would have to add them to a temporary 1D array in groups of 4 and then reshape the temporary array into a (2,2,1) shape and then append the full temporary 2x2 numpy array to the empty one, essentially going from a 2,2,0 shape to a 2,2,1 shape.

Repeat as many times as needed. 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))

And then you can access the elements as a[0][0][0] a[0][0][1]

Sth weird is that when you are appending the temporary array to a it automatically reshapes it to shape (4,)

a = np.array([[],[],[],[]]) makes

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

This is an array of 0 elements, that contains floats, and has a shape (4,0) . Your reshape changes the shape, but not the number of elements - still 2*2*0=0.

This is not an array that contains other arrays.

Appending to an element of a produces a 1 element array with shape (1,)

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

Trying to assign it back to a[0,0] does nothing. Actually I would have expected an error. But in any case, it shouldn't and can't add an value to the array, that by definition, has 0 elements.

You must be thinking that you have defined a 2x2 array where each element can be an object, such as another array. To do that you need create the array differently.

For example:

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

I could use np.append to create a new array (though I don't generally recommend using np.append ). (but beware of a[0,0].append(1) , a list operation).

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

I could replace an element with a 2x2 array:

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

or a string

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

or another list

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)

There's a real difference between this (2,2) array of objects and a 3 or 4d array of floats, (2,2,?).


Here's how I'd perform the appends in your answer

create the (2,2,0) array directly:

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

and the (2,2,1) is simply range reshaped:

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 is just an alternate front end to concatenate . So I'll use that with explicit control over the axis. append is for Python users who persist in thinking in list terms.

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)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM