I have a numpy array U with shape (20, 50): 20 spatial points, in a space of 50 dimensions.
How can I transform it into a (20, 1, 50) array, i.e. 20 rows, 1 column, and each element is a 50 dimension point? Kind of encapsulating each row as a numpy array.
Context
The point is that I want to expand the array along the columns (actually, replicating the same array along the columns X times) using numpy.concatenate. But if I would do it straight away I would not get the result I want.
E.g., if I would expand it once along the columns, I would get an array with shape (20, 100). But what I would like is to access each element as a 50-dimensional point, so when I expand it I would expect to have a new U' with shape (20, 2, 50).
You can do U[:, None, :] to add a new dimension to the array.
You can also use reshape:
import numpy as np
a = np.zeros((20, 50))
print a.shape # (20, 50)
b = a.reshape((20, 1, 50))
print b.shape # (20, 1, 50)
Related
I have an array of shape (3, 250, 15).
I want to append to it a 2d array of shape (250,15) so that I have a final shape of (4,250,15).
I tried with dstack and np.stack but it does not work.
Can someone give me a suggestion ?
You need to add a dimension (in other words, an axis) to the 2-D array, for example:
import numpy as np
a = np.ones((3, 250, 15))
b = np.ones((250, 15))
c = np.vstack([a, b[None, :, :]])
Now c has shape (4, 250, 15).
If you're not into the None axis trick, you could achieve something similar with np.newaxis or np.reshape.
You can't append a 2D array to a 3D array directly, so you should first expand the axes of the smaller array to become 3D and then append normally. np.expand_dims(b, axis=0) will insert the missing first-axis to array b. Now append the two 3D arrays, np.append(a, b, axis=0).
import numpy as np
a = np.ones((3, 250, 15))
b = np.ones(( 250, 15))
b = np.expand_dims(b, axis=0)
c = np.append(a, b, axis=0)
which works as expected.
print(c.shape)
(4, 250, 15)
I have an array A of shape (30,) where each row has a list with 2000 elements. I want to convert this into a 2d array of shape (30, 2000). This is what I tried
A = np.reshape(A, (30, -1))
But, running this gives me an array of shape (30, 1) rather than (30, 2000). What should I do to get the correct shape?
where each row has a list with 2000 elements
As Ahmed Mohamed AEK points out in the comments this won't work as the numpy object is of shape (30,). One easy fix is to stack them into a 30 by 2000 np.array.
For example:
A = np.vstack(A)
or equvalently:
A = np.stack(A, axis=0)
I have a single 2D array that I want to stack identical versions of into a third dimension, specifically axis=1. The following code does the job, but it's very slow for a 2D array of size (300,300) stacked into a third-dimension of length 300.
arr_2d = arr_2d.reshape(arr_2d.shape[0],arr_2d.shape[1],1)
arr_3d = np.empty((sampling,sampling,sampling)) # allocate space
arr_3d = [arr_3d[:,:,i]==arr_2d for i in range(sampling)]
Is there a better, more efficient way of doing this?
You can use numpy.repeat after you add a new third dimension to stack on:
import numpy as np
arr = np.random.rand(300, 300)
# arr.shape => (300, 300)
dup_arr = np.repeat(arr.reshape(*arr.shape, 1), repeats=10, axis=-1)
# dup_arr.shape => (300, 300, 10)
As commented by #xdurch0 and since you're stacking your copies along the last dimension, you can also use numpy.tile:
dup_arr = np.tile(arr.reshape(*arr.shape, 1), reps=10)
# dup_arr.shape => (300, 300, 10)
I want to merge two dimensions (y,z) of a 3D array (x,y,z) into one. Each corresponding value from y should be copied next to z.
For eg. I have 100 frames of a video with coordinates of 15 key points in 3 dimensions. The array shape is (100,15,3). I want output as (100, 45), which is merging y and z as 15x3.
Just use numpy.reshape. It can be used to flatten dimensions selectively.
import numpy as np
mat_3d = np.random.randn(2, 3, 4)
mat_2d = mat_3d.reshape((mat_3d.shape[0], -1))
print(mat_3d)
print(mat_2d)
In this example, I'm using (mat_3d.shape[0], -1) as argument of reshape. It means that the first dimension must stay unchanged, but all the other ones must be flatten (-1 is extra sugar to let numpy infers the right size, but using np.prod(mat_3d.shape[1:]) would be the same).
In such as case, Numpy first fetches values across the last axis (z here), then the second to last axis (y here), and so on and so forth in higher dimension.
I want to repeat a 1D-array along the dimensions of another array, knowing that this number of dimensions can change.
For example:
import numpy as np
to_repeat = np.linspace(0, 100, 10)
base_array = np.random.random((24, 60)) ## this one can have more than two dimensions.
final_array = np.array([[to_repeat for i in range(base_array.shape[0])] for j in range(base_array.shape[1])]).T
print(final_array.shape)
# >>> (10, 24, 60)
How can this be extended to an array base_array with an arbitrary number of dimensions?
Possibly using numpy vectorized functions in order to avoid loops?
EDIT (bigger picture):
base_array is in fact of shape (10, 24, 60) (if we stick to this example), where the coordinates along the first dimension are the vector to_repeat.
I'm looking for the minimum along the first dimension of base_array, and create the array of corresponding coordinates, here of shape (24, 60).
You don't need final_array, you can get the result you want by:
to_repeat[base_array.argmin(0)]