Stack dimensions of numpy array - python

I have a numpy array of shape (2500, 16, 32, 24), and I want to make it into a ( something, 24) array, but I don't want numpy to shuffle my values. The 32 x 24 dimension at the end represent images and I want the corresponding elements to be consistent. Any ideas?
EDIT: Ok , I wasn't clear enough. (something, 24) = (1280000, 24).

Use arr.reshape(-1,arr.shape[-1]) or if you know it will be 24 arr.reshape(-1,24)

Related

Creating sub arrays from 1D array - Python

I have searched the Internet to try and find a solution and have tried to make my own but can't seem to figure it out.
I need to be able to take a 1D NumPy array and within that array, after every 1024 values they get turned into a 32x32 array and keep going until the initial array has been completely searched through and to avoid any errors simply append any zeros necessary to fill up the sub-arrays.
Any help or guidance would be appreciated!
You don't really need to do much. First pad the array to the nearest multiple of 1024:
arr = np.random.rand(1024 * 5 - 100)
pad = -arr.size % 1024
if pad:
arr = np.concatenate((arr, np.zeros(pad, dtype=arr.dtype)))
Then reshape into an array of shape (N, 32, 32):
imgs = arr.reshape(-1, 32, 32)
Now you have a stack of images. Indexing imgs or iterating over it will give you the individual (32, 32) images.

Flatten a tiled array

I have a tiled numpy array of shape (16, 32, 16, 16), that is each tile is 16x16 pixels in a grid 32 tiles wide and 16 high.
From here I want to reshape it to a 256 high x 512 wide 2D image, and I can't quite find the right incantation of splits, slices, and reshapes to get to what I want.
You can combine numpy's reshape and transpose to get this job done. I am not entirely sure which of the three "16"s belongs to the 32x16 repetition grid, but assuming it's the first one:
import numpy as np
data = np.random.random((16, 32, 16, 16))
# put number of repetitions next to respective dimension
transposed_data = np.transpose(data, (0, 2, 1, 3))
# concatenate repeated dimensions via reshape
reshaped_data = transposed_data.reshape((16 * 16, 32 * 16))
print(reshaped_data.shape)

How can I convert an array of images to a 2D array in Python

I have a numpy array of images in that shape:
(50000, 32, 32, 3)
50000 is the number of images
32, 32 are the height and width
3 are the RGB values with a range of 0-1
I would like to convert it to a 2D shape of:
(50000, 1024)
Here I would have 50000 images represented in one row,
the RGB value would be converted to let's say an hexadecimal value
I've went through a lot of conversion processes into stack overflow and I've found some.
I know that if my array was a 3D array with an already converted value I could easily use reshape()function to convert it to 2D.
Now what I'm searching is the easiest way to convert RGB values and reshape my array
Would this be possible in 1 or two lines or should I use an external function?
First convert the RGB values in the last dimension to the HEX value using whatever function you like. This SO answer may help.
Reshape then works on any number of dimensions:
import numpy as np
def rgb2hex(r, g, b):
return '#%02x%02x%02x' % (r, g, b)
vfunc = np.vectorize(rgb2hex)
a = (np.random.uniform(0,1,(10,5,5,3))*255).astype(int)
c = vfunc(a[:,:,:,0], a[:,:,:,1], a[:,:,:,2])
c.reshape((10,25))
In order to do so, you firstly need to reshape the ndarray (np.reshape):
a = np.random.randint(1,10,(500, 32, 32, 3))
a_r = np.reshape(a, (500, 1024, 3))
print(a_r.shape)
# (500, 1024, 3)
Now, in order to convert the RGB values along the last dimension to hexadecimal representation as you suggest, you could define a function that returns a hexadecimal representation of the three values with a simple string formatting:
def rgb_to_hex(x):
return '#{:02X}{:02X}{:02X}'.format(*rgb.reshape(3))
In order to apply the conversion along all rows in the last axis, you can use np.apply_along_axis:
a_new = np.apply_along_axis(rgb2hex, axis=-1, arr=a_r).shape
print(a_new.shape)
# (500, 1024)
The following combines the RGB values into a single value
x=np.zeros((100,32,32,3))
x[:,:,:,0] = np.trunc(x[:,:,:,0]) + np.trunc(x[:,:,:,1] *256) + np.trunc(x[:,:,:,2] *65535)
y=x[:,:,:,0]
print(y.shape)
The resulting shape of y: (100, 32, 32)
Next you can use the reshape function on y.

Subtraction on numpy array not working

I have a 4D numpy array. I am trying to normalize it's value for that I need to subtract some value from it but the operation is adding the values.
Please help
print(X_train.shape)
print(X_train[0][0][0])
print(X_train[0][0][0]-128)
It's output is:
(34799, 32, 32, 3)
[28 25 24]
[156 153 152]
Shouldn't it be?
[-100,-103,-102]
Please let me know what I am doing wrong.
I am new to numpy.
The fact that it's a 4-dimensional array is not the point here.
I guess that your problem is with the data type of that numpy array. For example, if it's numpy.uint8 (unsigned byte, i.e. allowing only values in [0,255]) then subtracting 128 from 28 will give you 156... :)
Try: print (X_train.dtype) to see the data type associated with your numpy array.
If that's the case, then consider converting it to some other dtype, e.g. X_train = X_train.astype(numpy.int16), or simply to numpy.int8, depending on your expectations from your data.

Aligning N-dimensional numpy arrays

I am putting data in numpy arrays for comparisons. They way the data is stored sometimes the dimensions are out of order. For example if the first array has the shape (10, 20, 30, 40), sometimes the second array will have the shape (10, 20, 40, 30). We can assume that the lengths of the dimensions will be unique.
Is there an easy way to convert the shape of the second array to the shape of the first without knowing the number of dimensions or the length of the dimensions beforehand? I think I can do it with a long series of elif statements and transpose operations, but I'm hoping there is a cleaner method available.
Use shape.index to find where each axis needs to be, then use transpose to re-order the axes:
import numpy as np
A = np.ones((10, 20, 40, 30))
B = np.ones((10, 20, 30, 40))
new_order = [A.shape.index(i) for i in B.shape]
B = B.transpose(new_order)

Categories

Resources