how to add new elements to a numpy array - python

I created an array with size (256, 144, 3).
empty_windows = np.empty((256, 144, 3))
Then I want to append new elements into the array with:
for i in range(256):
for j in range(144):
empty_windows[i, j] = np.append(empty_windows[i, j], np.asarray(some_new_array)).reshape(3, )
But it doesnt work as I get the error msg:
ValueError: cannot reshape array of size 6 into shape (3,)
Is there a way of doing it? Thank you.

I hope, it will help you understanding concatenate 3dim array
import numpy as np
empty_windows = np.empty((256, 144, 3))
random_arr = np.random.randint(0, 100, size=(256, 144, 3)) # it's dimension should be same
np.concatenate([empty_windows, random_arr], axis=2) # it can concatenate into an array axis=2 defines 3rd dimension

np.empty and np.append are dangerous functions to use. They are not clones of the the empty list [] and list.append.
empty_windows = np.empty((256, 144, 3))
has made a (256,144,3) shape array with float values - they are unpredictable, but more than likely not what you want. Look at that array, or a smaller example to see for yourself. Also read, and if necessary reread, the np.empty docs. np.zeros is safer.
With scalar i,j,
empty_windows[i, j]
is a (3,) shape array, or slot.
When you np.append it with another (3,) shape, the result is a (6,) shape, with the first 3 value being those "random" values originally in empty_window. The error tells you quite clearly that it can't put a (6,) shape array into a slot that only holds (3,).
Your goal isn't clear, but you can't grow a (n,m,3) shape array to (n,m,6) by doing this kind of "row" by "row" append.
You can set the "row" with new values, as in:
empty_windows[i, j] = np.asarray(some_new_array)).reshape(3, )

Related

How do i add a dimension to a numpy array and copy the dimension from another numpy array

I have a numpy array with the shape (128, 8)
I want to add an extra dimension so it has the shape (128, 168, 8)
And add the content of a 168 dimension from another array that has the shape (128, 168, 8).
I can always permute the positions of the dimensions if I can somehow add it.
Is this possible somehow? I have seen the append and concatenation methods but to no luck.
you can also do:
small[:,None,:]+big
Adding None to indexing creates a new dimension of size 1, and adding to another bigger array will broadcast the small's size=1 dimension to bigger arrays corresponding dimension size (here will be 168)
np.expand_dims(smaller_array, axis=1) + bigger_array
Is the correct solution, thanks!

Vstack of two arrays with same number of rows gives an error

I have a numpy array of shape (29, 10) and a list of 29 elements and I want to end up with an array of shape (29,11)
I am basically converting the list to a numpy array and trying to vstack, but it complain about dimensions not being the same.
Toy example
a = np.zeros((29,10))
a.shape
(29,10)
b = np.array(['A']*29)
b.shape
(29,)
np.vstack((a, b))
ValueError: all the input array dimensions except for the concatenation axis must match exactly
Dimensions do actually match, why am I getting this error and how can I solve it?
I think you are looking for np.hstack.
np.hstack((a, b.reshape(-1,1)))
Moreover b must be 2-dimensional, that's why I used a reshape.
The problem is that you want to append a 1D array to a 2D array.
Also, for the dimension you've given for b, you are probably looking for hstack.
Try this:
a = np.zeros((29,10))
a.shape
(29,10)
b = np.array(['A']*29)[:,None] #to ensure 2D structure
b.shape
(29,1)
np.hstack((a, b))
If you do want to vertically stack, you'd need this:
a = np.zeros((29,10))
a.shape
(29,10)
b = np.array(['A']*10)[None,:] #to ensure 2D structure
b.shape
(1,10)
np.vstack((a, b))

Broadcast array in python

I want to reshape array of size (3,1) to (3,) with following code:
import numpy as np
a=np.random.random(size=(4,3,1))
a[1]=a[1].reshape(3,)
But getting following error:
ValueError: could not broadcast input array from shape (3) into shape (3,1)
how to solve it.
As per I understand, your array is consist of array of array (a.shape = (4,3,1)).
I do understand that a[1].shape = (3,1) seems to be not so different to a[1].shape = (3,), the program language however doesn't understand that way ((3,1) != (3,)) which means (3,1) and (3,) are totally different, since a[2],a[3] remain having shape = (3,1), every array within an array of array must have the same shape (3,1). Therefore, you need to reshape all the array at once or alternatively make a copy of a[1] to another variable and reshape this variable instead.
a = a.reshape(4,3)
and use a[1]
alternatively:
b = a[1]
b = b.reshape(3,)

Insert A numpy multi dimensional array inside another 1d array

I already have an array with shape (1, 224, 224), a single channel image. I want to change that to (1, 1, 224, 224). I have been trying
newarr.shape
#(1,224,224)
arr = np.array([])
np.append(arr, newarr, 1)
I always get this
IndexError: axis 1 out of bounds [0, 1). If i remove the axis as 0 , then the array gets flattened . What am I doing wrong ?
A dimension of 1 is arbitrary, so it sounds like you want to simply reshape the array. This can accomplished by:
newarr.shape = (1, 1, 244, 244)
or
newarr = newarr[None]
The only way to do an insert into a higher dimensional array is
bigger_arr = np.zeros((1, 1, 224, 224))
bigger_arr[0,...] = arr
In other words, make a target array of the right size, and assign values.
np.append is a booby trap. Avoid it.
Occasionally that's a useful way of thinking of this. But it's simpler, and quicker, to think of this as a reshape problem.
bigger_arr = arr.reshape(1,1,224,224)
bigger_arr = arr[np.newaxis,...]
arr.shape = (1,1,224,224) # a picky inplace change
bigger_arr = np.expand_dims(arr, 0)
This last one does
a.reshape(shape[:axis] + (1,) + a.shape[axis:])
which gives an idea of how to deal with dimensions programmatically.

How to get these shapes to line up for a numpy matrix

I'm trying to input vectors into a numpy matrix by doing:
eigvec[:,i] = null
However I keep getting the error:
ValueError: could not broadcast input array from shape (20,1) into shape (20)
I've tried using flatten and reshape, but nothing seems to work
The shapes in the error message are a good clue.
In [161]: x = np.zeros((10,10))
In [162]: x[:,1] = np.ones((1,10)) # or x[:,1] = np.ones(10)
In [163]: x[:,1] = np.ones((10,1))
...
ValueError: could not broadcast input array from shape (10,1) into shape (10)
In [166]: x[:,1].shape
Out[166]: (10,)
In [167]: x[:,[1]].shape
Out[167]: (10, 1)
In [168]: x[:,[1]] = np.ones((10,1))
When the shape of the destination matches the shape of the new value, the copy works. It also works in some cases where the new value can be 'broadcasted' to fit. But it does not try more general reshaping. Also note that indexing with a scalar reduces the dimension.
I can guess that
eigvec[:,i] = null.flat
would work (however, null.flatten() should work too). In fact, it looks like NumPy complains because of you are assigning a pseudo-1D array (shape (20, 1)) to a 1D array which is considered to be oriented differently (shape (1, 20), if you wish).
Another solution would be:
eigvec[:,i] = null.T
where you properly transpose the "vector" null.
The fundamental point here is that NumPy has "broadcasting" rules for converting between arrays with different numbers of dimensions. In the case of conversions between 2D and 1D, a 1D array of size n is broadcast into a 2D array of shape (1, n) (and not (n, 1)). More generally, missing dimensions are added to the left of the original dimensions.
The observed error message basically said that shapes (20,) and (20, 1) are not compatible: this is because (20,) becomes (1, 20) (and not (20, 1)). In fact, one is a column matrix, while the other is a row matrix.

Categories