Suppose there are 4D matrix (3,4,6,1) and 2D array (6,4) , I want to attach the 2D array left side of 2D matrix[0:3][0:4].
I can only do this problem using for loop.
for i in range(0, cols):
for j in range(0, rows):
x = np.append(a[i][j], b, axis = 1)
I try to make 2D -> 4D and use np.append ,but still don't know how to make 2D-> 4D like (3,4,6,4).
If I understand your requirements correctly one simple way would be
out = np.empty((3, 4, 6, 5))
out[..., :1] = a
out[..., 1:] = b
Related
How do I combine N, 2D numpy arrays (of dimension R x C) to create a 3D numpy array of shape (N, R, C)? Right now, the N-2D numpy arrays are contained inside a list, and I want that to become a 3D numpy array. Let's say X is my list of 2D numpy arrays, if I just do np.array(X), I get something of shape (N,). If I do np.vstack(X), I get something of shape (N x R, C). How do I solve this problem?
You can use np.stack:
test = np.stack([np.ones([2, 3]) for _ in range(4)])
print(test.shape) # (4, 2, 3)
you could just use :
np.array([np.array(x) for x in ArrayList])
Basically, is there a way to transform a 1D list that has been "flattened" through the numpy.ravel() function back to it's original 3D form ? I know the dimensions, and one might ask why I just don't use the original 3D array in the first place, instead of converting it - but there reasons for that.
I just need to know if I can actually create the same 3D array from a 1D array that was created by using numpy.ravel() on the 3D array.
Basically the 3D array was created like this:
import numpy as np
nx = 50
ny = 40
nz = 150
x = np.linspace(1, 51, nx)
y = np.linspace(1, 41, ny)
z = np.linspace(1, 151, nz)
x_bc = x[:, np.newaxis, np.newaxis]
y_bc = y[np.newaxis, :, np.newaxis]
z_bc = z[np.newaxis, np.newaxis, :]
arr = x_bc + y_bc + z_bc
And nope, I can't just do this to get it back, since calculations has been done to it in the mean time, and then converted to a 1D array in the mean time as well. So the data in this array is not the same as the one I actually want to convert back.
Just reshape it back to the original shape?
raveled = np.ravel(arr)
new_arr = raveled.reshape(*arr.shape)
Does numpy.reshape do what you want?
A trick when you want to flatten a matrix X of shape (a,b,c,d) to a matrix X_flatten of shape (b ∗∗ c ∗∗ d, a) is to use:
X_flatten = X.reshape(X.shape[0], -1).T
I read this trick in coursera DL course, how does this work? Where did -1 come from and what does it mean?
X.shape[0] returns the first dimension of your original array:
X = np.random.rand(4, 4, 4, 4)
print(X.shape)
results in
(4, 4, 4, 4)
and therefore
X.shape[0]
returns
4
Using the reshape command, you can omit one of the target matrix dimensions by using -1 as a placeholder,
because one of the dimensions can be inferred by numpy.
I.e. by supplying the 4 from X.shape[0], numpy knows what the remaining first dimension must be for the array to contain all your values.
In the example
new_X = X.reshape(X.shape[0], -1).T
print(new_X.shape)
it is
(64, 4)
which would be equivalent to calling
new_X = X.reshape(X.shape[0], 64).T
print(new_X.shape)
The .T function just transposes the array resulting from the reshape command.
We can do the same in, Using the basic concepts of python
nested_list=[10,20,[30,40,[50]],[80,[10,[20]],90],60]
flat_list=[]
def unpack(list1):
for item in list1:
try:
len(item)
unpack(item)
except:
flat_list.append(item)
unpack(nested_list)
print (flat_list)
I have a 4D array: array = np.random.rand(3432,1,30,512)
I also have 5 sets of 2D arrays with shape (30,512)
I want to insert these into the 4D structure along axis 1 so that my final shape is (3432,6,30,512) (5 new arrays + the original 1). I need to iteratively insert this set for each of the 3432 elements
Whats the most effective way to do this?
I've tried reshaping the 2D to 4D and then inserting along axis 1. I'm expecting axis 1 to never exceed a size of 6, but the 2D arrays just keep getting added, rather than a set for each of the 3432 elements. I think my problem lies in not fully understanding the obj param for the insert method:
all_data = np.reshape(all_data, (-1, 1, 30, 512))
for i in range(all_data.shape[0]):
num_band = 1
for band in range(5):
temp_trial = np.zeros((30, 512)) # Just an example. values arent actually 0
temp_trial = np.reshape(temp_trial, (1,1,30,512))
all_data = np.insert(all_data, num_band, temp_trial, 1)
num_band += 1
Create an array with the final shape first and insert the elements later:
final = np.zeros((3432,6,30,512))
for i in range(3432): # note, this will take a while
for j in range(6):
final[i, j, :, :] = # insert your array here (np.ones((30, 512)))
or if you actually want to broadcast this over the zeroth axis, assuming each of the 3432 should be the same for each "band":
for i in range(6):
final[:, i, :, :] = # insert your array here (np.ones((30, 512)))
As long as you don't do many loops there is no need to vectorize it
I have a 2D numpy array input_array and two lists of indices (x_coords and y_coords). Id like to slice a 3x3 subarray for each x,y pair centered around the x,y coordinates. The end result will be an array of 3x3 subarrays where the number of subarrays is equal to the number of coordinate pairs I have.
Preferably by avoiding for loops. Currently I use a modification of game of life strides from the scipy cookbook:
http://wiki.scipy.org/Cookbook/GameOfLifeStrides
shape = (input_array.shape[0] - 2, input_array.shape[0] - 2, 3, 3)
strides = input_array.strides + input_array.strides
strided = np.lib.stride_trics.as_strided(input_array, shape=shape, strides=strides).\
reshape(shape[0]*shape[1], shape[2], shape[3])
This creates a view of the original array as a (flattened) array of all possible 3x3 subarrays. I then convert the x,y coordinate pairs to be able to select the subarrays I want from strided:
coords = x_coords - 1 + (y_coords - 1)*shape[1]
sub_arrays = strided[coords]
Although this works perfectly fine, I do feel it is a bit cumbersome. Is there a more direct approach to do this? Also, in the future I would like to extend this to the 3D case; slicing nx3x3 subarrays from a nxmxk array. It might also be possible using strides but so far I haven't been able to make it work in 3D
Here is a method that use array broadcast:
x = np.random.randint(1, 63, 10)
y = np.random.randint(1, 63, 10)
dy, dx = [grid.astype(int) for grid in np.mgrid[-1:1:3j, -1:1:3j]]
Y = dy[None, :, :] + y[:, None, None]
X = dx[None, :, :] + x[:, None, None]
then you can use a[Y, X] to select blocks from a. Here is an example code:
img = np.zeros((64, 64))
img[Y, X] = 1
Here is graph ploted by pyplot.imshow():
A very straight forward solution would be a list comprehension and itertools.product:
import itertools
sub_arrays = [input_array[x-1:x+2, y-1:y+2]
for x, y in itertools.product(x_coords, y_coords)]
This creates all possible tuples of coordinates and then slices the 3x3 arrays from the input_array.
But this is sort-of a for loop. And you will have to take care, that x_coords and y_coords are not on the border of the matrix.