2

I have a Numpy array of shape (5,5,3,2). I want to take the element (1,4) of that matrix, which is also a matrix of shape (3,2), and add an element to it -so it becomes a (4,2) array. The code I'm using is the following:

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)

I'm always obtaining the error:

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

I understand that the shape returned by the np.append function is not the same as the a[2][3] sub-array, but I thought that the dtype=object would solve my problem. However, I need to do this. Is there any way to go around this limitation? I also tried to use the insert function but I don't know how could I add the element in the place I want.

1
  • This only makes sense if you change every 3 x 2 element to 4 x 2, other wise the dimensions won't work out. Commented Jul 20, 2016 at 15:54

3 Answers 3

1

Make sure you understand what you have produced. That requires checking the shape and dtype, and possibly looking at the values

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] is also an array. b[2,3] is the proper numpy way of indexing 2 dimensions.

I suspect you wanted b to be a (5,5) array containing arrays (as objects), and you think that you you can simply replace one of those with a (4,2) array. But the b constructor simply changes the floats of a to objects, without changing the shape (or 4d nature) of b.

I could construct a (5,5) object array, and fill it with values from a. And then replace one of those values with a (4,2) array:

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)

This constructor for B is a bit crude. I've answered other questions about creating/filling object arrays, but I'm not going to take the time here to streamline this case. It's for illustration purposes only.

Sign up to request clarification or add additional context in comments.

Comments

1

In an array of object, any element can be indeed an array (or any kind of 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

However a[2][3] is not an array element, it is a whole array.

a[2][3].ndim # 2

Therefore when you do a[2][3] = (something) you are using broadcasting instead of assigning an element: numpy tries to replace the content of the subarray a[2][3] and fails because of shape mismatch. The memory layout of numpy arrays does not allow to change the shape of subarrays.

Edit: Instead of using numpy arrays you could use nested lists. These nested lists can have arbitrary sizes. Note that the memory is higher and that the access time is higher compared to numpy array.

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

1 Comment

@V_Programmer I edited my answer to add a workaround with nested lists. But I don't know any way to do it with numpy arrays.
0

The problem here, is that you try to assign to a[2][3] Make a new array instead.

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

3 Comments

But if I do that, a does not change. I need to update that table with the new values. Creating a new array is useless.
@V_Programmer oh in that case you need to change every element. not a[2][3], but also a[n[n]. To keep the shape, so it will be (5,5,2,4)
could you edit your answer to add an example please?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.