How to add a new column to a 4d numpy array - python

I am trying to add a new column to my image dataset.
Sample Code:
import numpy as np
A = np.arange(240).reshape(3,4,4,5)
print(type(A))
print(A.shape)
B = np.concatenate([A, np.ones((A.shape[0],4,4,5,1),dtype=int)], axis=1)
print(B.shape)
Gives error:
ValueError: all the input arrays must have same number of dimensions
Context:
Consider this as m samples of read images (nH=height, nW=Weight, nC=channels).
Dataset is of shape (m, nH, nW, nC )and now I want to add additional column reflecting the image is of "good" example or "bad" example of an object.
Thus, want to create a dataset with label added in the dataset to form shape : (m,nH,nW,nC,l) where l stands for label and can have values either 0 or 1.
How can i achieve this? Thanks in advance.

Even simpler without reshaping :
A = np.random.rand(3, 4, 4, 5)
B = A[None] # Append a new dimension at the beginning, shape (1, 3, 4, 4, 5)
B = A[:,:,None] # Append a new dimension in the middle, shape (3, 4, 1, 4, 5)
B = A[:,:,:,:,None] # Append a new dimension at the end, shape (3, 4, 4, 5, 1)
Basically, the position of None indicates where to add the new dimension.

You don't need to add the fifth column explicitly. Just reshape and add the fifth dimension.
import numpy as np
A = np.arange(240).reshape(3,4,4,5,1) # add the fifth dimension here
print(type(A))
print(A.shape)
To set the "good" or "bad" label, just access the last dimension of A

Related

RuntimeError: Sizes of arrays must match except in dimension 1

I have a list of different shapes array that I wish to stack. Of course, np.stack doesn't work here because of the different shapes so is there a way to handle this using np.stack on dim=1?
is it possible to stack these tensors with different shapes along the second dimension so I would have the result array with shape [ -, 2, 5]? I want the result to be 3d.
data = [np.random.randn([2, 5]), np.random.randn([3, 5])]
stacked = np.stack(data, dim=1)
I tried another solution
f, s = data[0].shape, data[1].shape
stacked = np.concatenate((f.unsqueeze(dim=1), s.unsqueeze(dim=1)), dim=1)
where I unsqueeze the dimension but I also get this error:
RuntimeError: Sizes of arrays must match except in dimension 1. Expected size 2 but got size 3 for array number 1 in the list.
another solution that didn't work:
l = torch.cat(f[:, None, :], s[:, None, :])
the expected output should have shape [:, 2, 4]
Stacking 2d arrays as in your example, to become 3d, would require you to impute some missing data. There is not enough info to create the 3d array if the dimensions of your input data don't match.
I see two options:
concatenate along axis = 1 to get shape (5, 5)
a = data[0]
b = data[1]
combined = np.concatenate((a, b)) # shape (5, 5)
add dummy rows to data[0] to be able to create a 3d result
a = data[0]
b = data[1]
a = np.concatenate((a, np.zeros((b.shape[0] - a.shape[0], a.shape[1]))))
combined = np.stack((a, b)) # shape (2, 3, 5)
Another option could be to delete rows from data[1] to do something similar as option 2), but deleting data is in general not recommended.

Can't reshape color palette tuples using numpy

I have the following code which gets the color palette from series of images and try to reshape the output using numpy reshape. but when I try reshaping the output I get the error can't reshape array of size 27 into shape (3,3).
The output of Colours array print out is like this
[(256,256,265),(256,256,265),(256,256,265),(256,256,265),(256,256,265),(256,256,265),(256,256,265),(256,256,265),(256,256,265)]
Which are 9 tuples containing the colour palette which supposedly can be reshaped into 3 * 3
But numpy.reshape keeps saying it is 27 items and can't be reshaped into 3*3 array,
My question is how can I reshape this output into 3 * 3 array
So The colour array I need after reshaping should look something like this:
colours=[
[(256,256,265),(256,256,265),(256,256,265)],
[(256,256,265),(256,256,265),(256,256,265)],
[(256,256,265),(256,256,265),(256,256,265)]
]
from PIL import Image
import numpy as np
array=[]
for row in range(1,4):
for column in range(1,4):
filename = '/storage/emulated/0/python/banana/banana_0'+str(row)+'_0'+str(column)+'.png'
img = Image.open(filename)
img.show()
colors = img.getpixel((10,10))
array.append(colors)
array=np.array(array)
box_array=array.reshape(3,3)
You need to reshape using the full destination shape. Your array contains 27 elements in total
When you do:
array = np.array(array)
you obtain a (9, 3) shaped array, so you can't reshape it in (3, 3), but in (3, 3, 3).
you can proceed like:
box_array = array.reshape(3, 3, 3)
Depending on what dimension is subject to change in your array later, you can let numpy figure it out.
If for instance your 2nd and 3rd dimensions will always be (3, 3), then you can reshape your array as follows and numpy will detect automatically the 1st dimension:
box_array = array.reshape(-1, 3, 3)
And inversely if your 1st and 2nd dimensions will always be (3, 3), then you can reshape your array as follows and numpy will detect automatically the 3rd dimension:
box_array = array.reshape(3, 3, -1)

How I can add one floor, one row and one extra columns ´to my existing array containing data

I want to add one floor, one row and one columns into my existing 3-D matrix without losing the original information from the matrix
import numpy as np
tensor = np.zeros((len(subjects), len(properties) , len(objects)))
#subjects are 4, properties are 5 and objects are 7 in my case.
print(tensor.shape)
(4, 5, 7)
so I need to add one on more floor, row and columns, so it will give me the following output
so it will give me
print(tensor.shape)
(5,6,8)
numpy.pad is your friend.
>>> tensor = np.pad(tensor, (0,1), 'constant')
>>> tensor.shape
(5,6,8)
Numpy's insert function should help you here. Using the axis parameter helps to change which dimension/axis you are inserting into.
print(np.insert(tensor, 0, 0, axis=0).shape)
(5,5,7)
print(np.insert(tensor, 0, 0, axis=1).shape)
(4,6,7)
print(np.insert(tensor, 0, 0, axis=2).shape)
(4,5,8)
So if you need to do these inserts one at a time, this could be your best bet.
In each insert a column or row or height is added:
tensor = np.zeros((4, 5 , 6))
tensor=np.insert(tensor,[4],tensor[1,:,:],axis=0)
tensor=np.insert(tensor,[5],tensor[1,1,:],axis=1)
tensor=np.insert(tensor,[6],[0],axis=2)
print(tensor.shape)
Output: (5, 6, 7)

How To ReShape a Numpy Array in Python

I have a numpy array of images with the shape of (5879,). Inside every index of the numpy array, I have the Pixels of the image with a shape of (640,640,3).
I want to reshape the complete array in such a way that the shape of the numpy array becomes (5879,640,640,3).
please check, whether below code works for you or not
import numpy as np
b = np.array([5879])
b.shape
output (1,)
a = np.array([[640],[640],[3]])
a = a.reshape((a.shape[0], 1))
a.shape
output (3, 1)
c = np.concatenate((a,b[:,None]),axis=0)
c.shape
Output:
(4, 1)
np.concatenate((a,b[:,None]),axis=0)
output
array([[ 640],
[ 640],
[ 3],
[5879]])
You want to stack your images along the first axis, into a 4D array. However, your images are all 3D.
So, first you need to add a leading singleton dimension to all images, and then to concatenate them along this axis:
imgs = [i_[None, ...] for i_ in orig_images] # add singleton dim to all images
x = np.concatenate(imgs, axis=0) # stack along the first axis
Edit:
Based on Mad Phyiscist's comment, it seems like using np.stack is more appropriate here: np.stack takes care of adding the leading singleton dimension for you:
x = np.stack(orig_images, axis=0)

adding matrices to n dimensional array with numpy

Perhaps a simple questions, but I am using numpy, and iteratively generating 9x9x9 matrices.
I would like to stack these so I end up with Nx9x9x9, but using append, stack and stack it seems to vectorise one of the dimensions rather than add these as individual objects. any ideas how I can do this?
thanks
This could be resolved using np.vstack but to get this in the shape you want to need to add another dimension (an empty one) as first. Otherwise you would stack you current first dimension:
import numpy as np
a = np.ones((1,2,2,2))
print(a.shape) # (1, 2, 2, 2)
or if you create your arrays, then add another dimension by:
a = np.ones((2,2,2))
a = a[None, :] # Adds an dimension as first
and then to stack them you could use:
b = np.vstack([a,a])
print(b.shape) # (2, 2, 2, 2)
c = np.vstack([b,a])
print(c.shape) # (3, 2, 2, 2)
c.shape
you said you create them iterativly but if you only need the final result at the end you don't even need to use vstack just create a new array:
a = np.ones((9,9,9))
b = np.ones((9,9,9))
c = np.ones((9,9,9))
d = np.ones((9,9,9))
res = np.array([a, b, c, d])
print(res.shape) # (4, 9, 9, 9)

Categories

Resources