I have two numpy arrays, one with shape let's say (10, 5, 200), and another one with the shape (1, 200), how can I stack them so I get as a result an array of dimensions (10, 6, 200)? Basically by stacking it to each 2-d array iterating along the first dimension
a = np.random.random((10, 5, 200))
b = np.zeros((1, 200))
I'v tried with hstack and vstack but I get an error in incorrect number of axis
Let's say:
a = np.random.random((10, 5, 200))
b = np.zeros((1, 200))
Let's look at the volume (number of elements) of each array:
The volume of a is 10*5*200 = 10000.
The volume of an array with (10,6,200) is 10*5*200=1200.
That is you want to create an array that has 2000 more elements.
However, the volume of b is 1*200 = 200.
This means a and b can't be stacked.
As hpaulj mentioned in the comments, one way is to define an numpy array and then fill it:
result = np.empty((a.shape[0], a.shape[1] + b.shape[0], a.shape[2]))
result[:, :a.shape[1], :] = a
result[:, a.shape[1]:, :] = b
Related
I have a 2D array of shape (10, 3) and an image represented as a 3D array of shape (480, 640, 3). I'd like to perform a difference between each pixel and each element of the 2D array, to get a final result of shape (10, 480, 640, 3).
For now, my code looks like this:
arr_2d = np.random.rand(10, 3)
arr_3d = np.random.rand(480, 640, 3)
res = np.ones_like(arr_3d)
res = np.tile(res, (10, 1, 1, 1))
for i in range(10):
res[i] = arr_3d - arr_2d[i]
My question is if there's a way to do this without the for loop, only using numpy operations.
You can try broadcasting with np.array like this
arr_2d = arr_2d.reshape(-1,1,1,3)
arr_3d = arr_3d.reshape((-1,*arr_3d.shape))
res = arr_3d - arr_2d
This should give the same result as your original code
I am new on Python and I don't know exactly how to perform multiplication between arrays of different shape.
I have two different arrays w and b such that:
W.shape = [32, 5, 20]
b.shape = [5,]
and I want to multiply
W[:, i, :]*b[i]
for each i from 0 to 4.
How can I do that? Thanks in advance.
You could add a new axis to b so it is multiplied accross W's inner arrays' rows, i.e the second axis:
W * b[:,None]
What you want to do is called Broadcasting. In numpy, you can multiply this way, but only if the shapes match according to some restrictions:
Starting from the right, every component of each arrays' shape must be the equal, 1, or not exist
so right now you have:
W.shape = (32, 5, 20)
b.shape = (5,)
since 20 and 5 don't match, they cant' be broadcast.
If you were to have:
W.shape = (32, 5, 20)
b.shape = (5, 1 )
20 would match with 1 (1 is always ok) and the 5's would match, and you can then multiply them.
To get b's shape to (5, 1), you can either do .reshape(5, 1) (or, more robustly, .reshape(-1, 1)) or fancy index with [:, None]
Thus either of these work:
W * b[:,None] #yatu's answer
W * b.reshape(-1, 1)
I need to insert 3-dimensional matrices into a new variable.
I'm trying to do that by:
Creating a 4-dimensional matrix and by promoting the fourth dimension saving the three dimensions respectively.
Sample code:
from python_speech_features import mfcc
import numpy as np
X = np.zeros((0,0,0,0),float) #4-dimensional - (0, 0, 0, 0)
ii = 0
for ii in range 1000:
data, fs = sf.read(curfile[ii])
sig = mfcc(data, fs, winstep=winstep,winlen=winlen,nfft=1024) #size - (49, 13)
sig = sig[:, :, np.newaxis] #add third-dimensional - (49, 13, 1)
X[:,:,:,ii] = sig
Error:
IndexError: index 0 is out of bounds for axis 3 with size 0
Someone can help me with that problem?
You are not creating array in right way. You cannot insert value in axis which have zero length at least specify some length for axis
X = np.zeros((10, 10, 10,1000), float)
print(X.shape)
# (10, 10, 10, 1000)
Now you can set value in whatever axis you want by simply,
X[:, :, :, 2] = 1
# this will simply set value of 3rd axis's 3rd element to 1
Either use np.stack (i think it is the best way of doing it) or create the initial array in its final size:
np.zeros((49,13,1,1000), float)
In your case
I have a numpy array of points with shape (1000,3)
where axis 1 takes on values [x,y,1]
The points are at discrete values on a grid so an example array looks like:
array=([1,2,1],[4,5,1],[2,3,1],...,[xN,yN,1])
I would like to dilate this 2d array, and by this I mean, for each [x,y,1] coordinate in the array, if [x±1,y±1,1] is not in the array append it to the array.
currently I'm doing this with the following code:
np.append(array, [array[:,0],array[:,1]+1,1])
np.append(array, [array[:,0]+1,array[:,1],1])
np.append(array, [array[:,0]+1,array[:,1]+1,1])
np.append(array, [array[:,0]-1,array[:,1],1])
np.append(array, [array[:,0],array[:,1]-1,1])
np.append(array, [array[:,0]-1,array[:,1]-1,1])
np.append(array, [array[:,0]+1,array[:,1]-1,1])
np.append(array, [array[:,0]-1,array[:,1]+1,1])
then I am using np.unique(array) to reduce down to unqiue elements. This method works, but it is too slow to run on large arrays with more than 100000 points, and it doesn't feel like a smooth solution. There must be a way to do this without duplicating so many points then having to find all unique instances. Is there a different (read:faster) way to do what I am doing?
2000 x 4000 x 200 is just doable with a lookup table. At just below a million coordinates I get a speedup by a factor of ~5 compared to the np.unique approach.
lookup table: 2.18715, np.unique: 11.40247
Code:
import numpy as np
from numpy.lib.stride_tricks import as_strided
from time import time
coords = np.unique(np.random.randint(0, 2000*4000*200, (1000000,)))
coords = np.c_[coords // (4000*200), (coords // 200) % 4000, coords % 200]
t = [time()]
ws = np.empty((2002, 4002, 202), dtype=np.uint8)
ws = as_strided(ws, (2000, 4000, 200, 3, 3, 3), 2 * ws.strides)
ws[tuple(coords.T)] = np.arange(27).reshape(3, 3, 3)
unq = ws[tuple(coords.T)] == np.arange(27).reshape(3, 3, 3)
result = (coords[:, None, None, None, :] + np.moveaxis(np.indices((3, 3, 3)) - 1, 0, -1))[unq]
del ws
t.append(time())
result2 = np.unique((coords[:, None, None, None, :] + np.moveaxis(np.indices((3, 3, 3)) - 1, 0, -1)).reshape(-1, 3), axis = 0)
t.append(time())
print('lookup table: {:8.5f}, np.unique: {:8.5f}'.format(*np.diff(t)))
i have 3 numpy arrays which store image data of shape (4,100,100).
arr1= np.load(r'C:\Users\x\Desktop\py\output\a1.npy')
arr2= np.load(r'C:\Users\x\Desktop\py\output\a2.npy')
arr3= np.load(r'C:\Users\x\Desktop\py\output\a3.npy')
I want to merge all 3 arrays into 1 array.
I have tried in this way:
merg_arr = np.zeros((len(arr1)+len(arr2)+len(arr3), 4,100,100), dtype=input_img.dtype)
now this make an array of the required length but I don't know how to copy all the data in this array. may be using a loop?
This will do the trick:
merge_arr = np.concatenate([arr1, arr2, arr3], axis=0)
np.stack arranges arrays along a new dimension. Their dimensions (except for the first) need to match.
Demo:
arr1 = np.empty((60, 4, 10, 10))
arr2 = np.empty((14, 4, 10, 10))
arr3 = np.empty((6, 4, 10, 10))
merge_arr = np.concatenate([arr1, arr2, arr3], axis=0)
print(merge_arr.shape) # (80, 4, 10, 10)