I'm having a 2D array of dummy variables (0 and 1) with the shape of (4432, 35) -> 4432 videos including 35 different customers. Since the videos contain of 1800 frames I want to add a third dimension to this array with 1800 time steps (frames) so that it gets the shape (4432, 35, 1800). So I want Python to multiplicate the zeros and ones in the 2nd dimension 1800 times into the 3rd dimension.
How can I do that?
with an array called array with any 2D shape:
array = [[[j for k in range(1800)] for j in i] for i in array]
This will create a 3rd dimension with 1800 duplicates of the values in the second dimension.
It also seems to make more sense to have a shape (4432, 1800, 35): (video, frame, customers in frame):
array = [[i for k in range(1800)] for i in array]
I have found a working code for this, but don't understand everything about these lines:
counter = np.unique(img.reshape(-1, img.shape[2]), axis=0)
print(counter.shape[0])
Especially these values:
-1, img.shape[2], axis=0
What does that -1 do, why is the shape 2, and why is axis 0?
And after that, why do we print shape[0]?
If you don't understand a complex sentence, always break them up and print shapes.
print(img.shape)
img2 = img.reshape(-1, img.shape[2]) # reshape the original image into -1, 3; -1 is placeholder, so lets say you have a
# numpy array with shape (6,2), if you reshape it to (-1, 3), we know the second dim = 3
# first dim = (6*2)/3 = 4, so -1 is replaced with 4
print(img2.shape)
counter = np.unique(img2, axis=0) # find unique elemenst
'''
numpy.unique(ar, return_index=False, return_inverse=False, return_counts=False, axis=None)[source]
Find the unique elements of an array.
Returns the sorted unique elements of an array. There are three optional outputs in addition to the unique elements:
the indices of the input array that give the unique values
the indices of the unique array that reconstruct the input array
the number of times each unique value comes up in the input array
'''
print(counter)
print(counter.shape) # as, we have separate axis, so the channels are shown in dim 2
print(counter.shape[0])
But, this one is probably not correct as it doesn't consider unique RGB across channel.
So, the following is a better one, you flatten the array to get a list then using set find the unique elements and finally print the len of the set.
A handy shortcut is ->
print(len(set(img.flatten())))
Try this:
a = np.array([
[[1,2,3],[1,2,3],[1,2,3],[1,2,3]],
[[1,2,3],[1,2,3],[1,2,3],[1,2,3]]
])
a # to print the contents
a.shape # returns 2, 4, 3
Now, if you do reshape, it will change the shape, meaning it will re-arrange the items in the array.
# try:
a.reshape(2, 4, 3)
a.reshape(4, 2, 3)
# or even
a.reshape(12, 2, 1)
a.reshape(1, 1, 4, 2, 3)
a.reshape(1, 1, 4, 2, 1, 1, 3)
# or:
a.reshape(24, 1)
a.reshape(1, 24)
If you replace one of the numbers with -1, it will get calculated automatically. So:
a.reshape(-1, 3)
# is the same as
a.reshape(8, 3)
and that'll give you the a "vector" of RGB values in a way.
So now you have got the reshaped array and you just need to count unique values.
np.unique(a.reshape(8, 3), axis=0)
will return an array of unique values over axis 0 and you will just count them.
It is calculating the number of unique RGB pixel values in the image. In other word it is calculation the number of different colors in the images
img.reshape(-1, img.shape[2]) : A three channel image flattened per channel. A 3 channel image is of shape width x height x 3 where each channels (3 here) corresponds to RGB or BGR depending on how you read the image. We are reshaping it into 2 dimensions, RGB values per channel. So second dimension will be number of channels. so if you know the width and height of image, it is equal to img.reshape(w*h, img.shape[2]) which is same as img.rehape(img.shape[0]*img.shape[1], img.shape[2]). Intutively think of it like you are taking a 3 channel image and laying out the colors of pixels one after the other. In numpy you can always leave out one dimension as -1 which is automatically calculated based on the shape of the object and the other dimensions.
Now that we have layed out pixes one after the other we can calculate the number of unique colors, but since color is represented by 3 (RGB) values we want to calculated unique RGB values which is done by using np.unique over the second dimension which is channel. This returns all the unique RGB values, which will be of size n x 3 where n are the unique pixel values. Finally since we want to find the count, shape will return (n,3) we select shape[0] which will return n.
Code
# image of size 200 X 200 X 3 => 200 pixels width 200 pixels height => total 200*200 pixels
img = np.random.randint(0,256, (200,200,3))
print (img.shape)
# Flatten the image to 200*200 pixels
img = img.reshape(-1, img.shape[2])
print (img.shape)
# Count unique colors
counter = np.unique(img, axis=0)
# n unique colors (3 values per pixel)
print (counter.shape)
Output
(200, 200, 3)
(40000, 3)
(39942, 3)
the question is:
In the keras tutorial it use an input x_train = np.random.random((100, 100, 100, 3)), it should means that there's 100 images each has size of [100,100,3] right?
So i thought that x_train[0][0] should represent the first channel of the first img (which should be [100, 100]), but x_train[0][0] in fact has a size of [100,3]... so i'm confused, how can keras take this [100,100,100,3] numpy array as a set of imgs? please help me out, thank in advance.
Another question is:
how can I construct a input like this ? Cause when I do np.array([[100,100],[100,100]]), it becomes to array of [2,100,100]
Here is an explanation on how you can access your images.
X is four dimensional tensor. In mathematics tensors are generalization of vectors and metrics into higher dimensional arrays.
Assuming "channels last" data-format
1st Axis = Number of images
2nd Axis = Number of rows in single image
3rd Axis = Number of columns in single row
4th Axis = Number of channels of certain pixel
Now you can access image,row,column, and channels using indexing as follows.
x[0] Represents first image
x[0][0] Represents First row of first image
x[0][0][0] Represents First column of first row of first image
x[0][0][0][0] Represents Red channel of First column of first row of first image
I have a 2D numpy array with the shape (3024, 4032).
I have a 3D numpy array with the shape (3024, 4032, 3).
2D numpy array is filled with 0s and 1s.
3D numpy array is filled with values between 0 and 255.
By looking at the 2D array values, I want to change the values in 3D array. If a value in 2D array is 0, I will change the all 3 pixel values in 3D array into 0 along the last axes. If a value in 2D array is 1, I won't change it.
I have checked this question, How to filter a numpy array with another array's values, but it applies for 2 arrays which have same dimensions. In my case, dimensions are different.
How the filtering is applied in two arrays, with same size on 2 dimensions, but not size on the last dimension?
Ok, I'll answer this to highlight one pecularity regarding "missing" dimensions. Lets' assume a.shape==(5,4,3) and b.shape==(5,4)
When indexing, existing dimensions are left aligned which is why #Divakar's solution a[b == 0] = 0 works.
When broadcasting, existing dimensions are right aligned which is why #InvaderZim's a*b does not work. What you need to do is a*b[..., None] which inserts a broadcastable dimension at the right
I think this one is very simple:
If a is a 3D array (a.shape == (5, 4, 3)) filled with values, and b is a 2D array (b.shape == (5, 4)) filled with 1 and 0, then reshape b and multiply them:
a = a * b.reshape(5, 4, 1)
Numpy will automatically expand the arrays as needed.
My numpy array (name: data) has following size: (10L,3L,256L,256L).
It has 10 images with each 3 color channels (RGB) and each an image size of 256x256 pixel.
I want to compute the mean pixel value for each color channel of all 10 images. If I use the numpy function np.mean(data), I receive the mean for all pixel values. Using np.mean(data, axis=1) returns a numpy array with size (10L, 256L, 256L).
If I understand your question correctly you want an array containing the mean value of each channel for each of the three images. (i.e. an array of shape (10,3) ) (Let me know in the comments if this is incorrect and I can edit this answer)
If you are using a version of numpy greater than 1.7 you can pass multiple axes to np.mean as a tuple
mean_values = data.mean(axis=(2,3))
Otherwise you will have to flatten the array first to get it into the correct shape.
mean_values = data.reshape((data.shape[0], data.shape[1], data.shape[2]*data.shape[3])).mean(axis=2)