Transform ndarray shape - python

I'm using python / Numpy to store small images into ndarray.
I'm stuck when I'm trying to transform an ndarray from 32,32,1 shape to 1,32,32,1. Any help ? Thanks

You need to expand the dimensions of the numpy array. Use np.expand_dims.
arr = np.expand_dims(arr, axis=0)

arr[np.newaxis, :, :, :] will work

Instead of explicitly adding an axis you could also explicitly reshape it to add the axis:
>>> import numpy as np
>>> arr = np.ones((32, 32, 1)) # just ones for demonstration purposes
>>> reshaped = arr.reshape(1, *arr.shape)
>>> reshaped.shape
(1, 32, 32, 1)

Related

Extend 1d numpy array in multiple dimensions

I have a 1d numpy array, e.g. a=[10,12,15] and I want to extend it so that I end up with a numpy array b with the shape (3,10,15,20) filled with a so that e.g. b[:,1,1,1] is [10,12,15].
I thought of using np.repeat but it's not clear to me how to do ?
tile will do it for you. Internally this does a repeat for each axis.
In [114]: a = np.array([10,12,15])
In [115]: A = np.tile(a.reshape(3,1,1,1),(1,10,15,20))
In [116]: A.shape
Out[116]: (3, 10, 15, 20)
In [117]: A[:,1,1,1]
Out[117]: array([10, 12, 15])
For some purposes it might be enough to just do the reshape and let broadcasting expand the dimensions as needed (without actually expanding memory use).
Code:
import numpy as np
a = np.arange(1800).reshape((10,12,15))
b = np.repeat(a, repeats=5, axis=0).reshape(((3,10,15,20)))
You can change axis if you want to repeat in a different fashion. To understand repeat use lower shape for e.g. a(3,5,4) and b (2,3,5,4) and repeat on different axis.

Matrix multiplication (element-wise) from numpy to Pytorch

I got two numpy arrays (image and and environment map),
MatA
MatB
Both with shapes (256, 512, 3)
When I did the multiplication (element-wise) with numpy:
prod = np.multiply(MatA,MatB)
I got the wanted result (visualize via Pillow when turning back to Image)
But when I did it using pytorch, I got a really strange result(not even close to the aforementioned).
I did it with the following code:
MatATensor = transforms.ToTensor()(MatA)
MatBTensor = transforms.ToTensor()(MatB)
prodTensor = MatATensor * MatBTensor
For some reasons, the shape for both MatATensor and MatBtensor is
torch.Size([3, 256, 512])
Same for the prodTensor too.
When I tried to reshape to (256,512,3), I got an error.
Is there a way to get the same result?
I am new to pytorch, so any help would be appreciated.
If you read the documentation of transforms.ToTensor() you'll see this transformation does not only convert a numpy array to torch.FloatTensor, but also transpose its dimensions from HxWx3 to 3xHxW.
To "undo" this you'll need to
prodasNp = (prodTensor.permute(2, 0, 1) * 255).to(torch.uint8).numpy()
See permute for more information.
I suggest you use torch.from_numpy, which will easily convert your ndarrays to torch tensors. As in:
In[1]: MatA = np.random.rand(256, 512, 3)
In[2]: MatB = np.random.rand(256, 512, 3)
In[3]: MatA_torch = torch.from_numpy(MatA)
In[4]: MatB_torch = torch.from_numpy(MatB)
In[5]: mul_np = np.multiply(MatA, MatB)
In[6]: mul_torch = MatA_torch * MatB_torch
In[7]: torch.equal(torch.from_numpy(mul_np), mul_torch)
Out[7]: True
In[8]: mul_torch.shape
Out[8]: torch.Size([256, 512, 3])
If you want it back to numpy, just do:
mul_torch.numpy()

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)

Numpy flatten RGB image array

I have 1,000 RGB images (64X64) which I want to convert to an (m, n) array.
I use this:
import numpy as np
from skdata.mnist.views import OfficialImageClassification
from matplotlib import pyplot as plt
from PIL import Image
import glob
import cv2
x_data = np.array( [np.array(cv2.imread(imagePath[i])) for i in range(len(imagePath))] )
print x_data.shape
Which gives me: (1000, 64, 64, 3)
Now if I do:
pixels = x_data.flatten()
print pixels.shape
I get: (12288000,)
However, I require an array with these dimensions: (1000, 12288)
How can I achieve that?
Apply the numpy method reshape() after applying flatten() to the flattened array:
x_data = np.array( [np.array(cv2.imread(imagePath[i])) for i in range(len(imagePath))] )
pixels = x_data.flatten().reshape(1000, 12288)
print pixels.shape
Try this:
d1, d2, d3, d4 = x_data.shape
then using numpy.reshape()
x_data_reshaped = x_data.reshape((d1, d2*d3*d4))
or
x_data_reshaped = x_data.reshape((d1, -1))
(Numpy infers the the value instead of -1 from original length and defined dimension d1)
You can iterate over your images array and flatten each row independently.
numImages = x_data.shape[0]
flattened = np.array([x_data[i].flatten() for i in range(numImages)])
You could also use this:
X is your 2D picture with size 32x32 for example and the -1 it simply means that it is an unknown dimension and we want numpy to figure it out. And numpy will figure this by looking at the 'length of the array and remaining dimensions' and making sure it satisfies the above mentioned criteria (What does -1 mean in numpy reshape?). T means to invert the transposition of tensors when using the axes keyword argument (https://docs.scipy.org/doc/numpy/reference/generated/numpy.transpose.html).
X_flatten = X.reshape(X.shape[0], -1).T
Assuming you have an array image_array you can use the reshape() method.
image_array = image_array.reshape(1000, 12288)

Subset a 3d numpy array

I have checked the numpy documentation but some of the indexing still eludes me. I have a numpy array such that its shape is (40000, 432) and its looks something like:
arr = [[1,2,3......431,432],
[1,2,3......431,432],
[1,2,3......431,432],
....................
[1,2,3......431,432]'
[1,2,3......431,432]]
I wanted to subset each array over a range (ie. 20-50) so that the shape will be (40000, 30) and it will look like:
subarr = [[20,21,22...48,49,50],
[20,21,22...48,49,50],
[20,21,22...48,49,50],
.....................
[20,21,22...48,49,50]]
Everything I try either returns me an error or gives me the shape (30, 432) which is not what I need. How do I subset a 2d array along the axis I want to?
You want to use numpy slicing:
arr = np.zeros((40000, 432))
subarr = arr[:, 20:50]
print(subarr.shape)
Output
(40000L, 30L)
The L in the shape output indicates that the integer is of Python type long.

Categories

Resources