Related
I have a 3D array consist of 2D arrays, I want to rotate only the 2D arrays inside the 3D array without changing the order, so it will become a 3D array consist of rotated 3D arrays.
For example, I have a 3D array like this.
foo = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
print(foo)
>>> array([[[ 1, 2, 3],
[ 4, 5, 6]],
[[ 7, 8, 9],
[10, 11, 12]]])
foo.shape
>>> (2, 2, 3)
I want to rotate it into this.
rotated_foo = np.array([[[4, 1], [5, 2], [6, 3]], [[10, 7], [11, 8], [12, 9]]])
print(rotated_foo)
>>> array([[[ 4, 1],
[ 5, 2],
[ 6, 3]],
[[10, 7],
[11, 8],
[12, 9]]])
rotated_foo.shape
>>> (2, 3, 2)
I've tried it using numpy's rot90 but I got something like this.
rotated_foo = np.rot90(foo)
print(rotated_foo)
>>> array([[[ 4, 5, 6],
[10, 11, 12]],
[[ 1, 2, 3],
[ 7, 8, 9]]])
rotated_foo.shape
>>> (2, 2, 3)
You can use numpy.rot90 by setting axes that you want to rotate.
foo = np.array([[[1, 2, 3], [4, 5, 6]], [[7, 8, 9], [10, 11, 12]]])
rotated_foo = np.rot90(foo, axes=(2,1))
print(rotated_foo)
Output:
array([[[ 4, 1],
[ 5, 2],
[ 6, 3]],
[[10, 7],
[11, 8],
[12, 9]]])
Try np.transpose and np.flip:
print(np.flip(np.transpose(foo, (0, 2, 1)), axis=2))
Prints:
[[[ 4 1]
[ 5 2]
[ 6 3]]
[[10 7]
[11 8]
[12 9]]]
You want to rotate 90 in the opposite direction of np.rot90, or equivalently rotate by 270 = 3 * 90 in the np.rot90 direction:
>>> np.rot90(foo, k=3, axes=(1, 2))
array([[[ 4, 1],
[ 5, 2],
[ 6, 3]],
[[10, 7],
[11, 8],
[12, 9]]])
I have been going over this issue with numpy for a while and cant figure out if there is a intuitive way of converting the array while maintaining the position of the sub-array. The sizes of the array will change depending on the input so doing it manually with concatenate is not an option but i do have the dimensions.
a= np.array([[[0,1],[2,3]],[[4,5],[6,7]],[[8,9],[10,11]],[[12,13],[14,15]]])
reshaping just flattens the array like
[1,2,3,4]
[5,6,7,8]
etc
I have also tried np.block but besides setting the positions manually i have not had any success
The result i would like to get in this case is (4,4):
[[ 0, 1, 4, 5],
[ 2, 3, 6, 7],
[ 8, 9,12,13],
[10,11,14,15]]
Does anyone of you smart people know if there is something in numpy that i could use to get this result?
Your original has the 16 consecutive values reshaped into 4d array:
In [67]: x=np.arange(16).reshape(2,2,2,2)
In [68]: x
Out[68]:
array([[[[ 0, 1],
[ 2, 3]],
[[ 4, 5],
[ 6, 7]]],
[[[ 8, 9],
[10, 11]],
[[12, 13],
[14, 15]]]])
Reshape to (4,4) keeps that original order - see the 0,1,2,3...
In [69]: x.reshape(4,4)
Out[69]:
array([[ 0, 1, 2, 3],
[ 4, 5, 6, 7],
[ 8, 9, 10, 11],
[12, 13, 14, 15]])
You want to swap values:
In [70]: x.transpose(0,2,1,3)
Out[70]:
array([[[[ 0, 1],
[ 4, 5]],
[[ 2, 3],
[ 6, 7]]],
[[[ 8, 9],
[12, 13]],
[[10, 11],
[14, 15]]]])
which can then be reshaped to (4,4):
In [71]: x.transpose(0,2,1,3).reshape(4,4)
Out[71]:
array([[ 0, 1, 4, 5],
[ 2, 3, 6, 7],
[ 8, 9, 12, 13],
[10, 11, 14, 15]])
Let's assume I have the following 4x4 matrix:
import numpy as np
np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,14,15,16]])
I wish to group the values in 2x2 submatrices, sum them and gather the result in a 2x2 matrix, so that the result in this case would be:
[
[14, 22],
[46, 54]
]
What is the most numpy-ish way to do so?
You can use .reshape method and then sum along axis:
import numpy as np
data = np.array([[1, 2, 3, 4],
[5, 6, 7, 8],
[9,10,11,12],
[13,14,15,16]])
bs = 2 #block size
data_r = data.reshape(bs,bs,bs,bs)
data_r
array([[[[ 1, 2],
[ 3, 4]],
[[ 5, 6],
[ 7, 8]]],
[[[ 9, 10],
[11, 12]],
[[13, 14],
[15, 16]]]])
data_r.sum(axis=(1,3))
array([[14, 22],
[46, 54]])
I have an input numpy array as follows:
import numpy as np
my_array = [
np.array([[[1, 10]],
[[2, 11]]], dtype=np.int32),
np.array([[[3, 12]],
[[4, 13]],
[[5, 14]]], dtype=np.int32),
np.array([[[6, 15]],
[[7, 16]],
[[8, 17]]], dtype=np.int32)
]
I want to get two arrays (1 for each column) so that:
array1 = [1, 2, 3, 4, 5, 6, 7 ,8]
array2 = [10, 11, 12, 13, 14, 15, 16, 17]
I tried with a list comprehension but it didn't work:
[col[:] for col in my_array]
You can loop through the arrays and append to the new ones:
array1 = []
array2 = []
for array in my_array:
for nested_array in array:
# nested_array is of form [[ 1 10]] here, you need to index it
# first with [0] then with the element you want to access [0] or [1]
array1.append(nested_array[0][0])
array2.append(nested_array[0][1])
You just have to think about the structure of the input data and how to get the values you need in the order that you need.
The output:
>>> array1
[1, 2, 3, 4, 5, 6, 7, 8]
>>> array2
[10, 11, 12, 13, 14, 15, 16, 17]
You can try this:
>>> from numpy import array
>>> import numpy as np
>>> my_array = [array([[[1, 10]],
[[2, 11]]], dtype='int32'), array([[[3, 12]],
[[4, 13]],
[[5, 14]]], dtype='int32'), array([[[6, 15]],
[[7, 16]],
[[8, 17]]], dtype='int32')]
# One way
>>> np.concatenate(my_array,axis=0)[...,0] # [...,1] would give the other one
array([[1],
[2],
[3],
[4],
[5],
[6],
[7],
[8]], dtype=int32)
# Other way:
>>> np.concatenate(my_array,axis=0)[...,0].reshape(-1,) # [...,1].reshape(-1,0) would be the other one
array([1, 2, 3, 4, 5, 6, 7, 8], dtype=int32)
I have an 2D-array a with shape (k,n) and I want to 'multiply' it with an 1D-array b of shape (m,):
a = np.array([[2, 8],
[4, 7],
[1, 2],
[5, 2],
[7, 4]])
b = np.array([3, 5, 5])
As a result of the 'multiplication' I'm looking for:
array([[[2*3,2*5,2*5],[8*3,8*5,8*5]],
[[4*3,4*5,4*5],[7*3,7*5,7*5]],
[[1*3,1*5,1*5], ..... ]],
................. ]]])
= array([[[ 6, 10, 10],
[24, 40, 40]],
[[12, 20, 20],
[21, 35, 35]],
[[ 3, 5, 5],
[ ........ ]],
....... ]]])
I could solve it with a loop of course, but I'm looking for a fast vectorized way of doing it.
Extend a to a 3D array case by adding a new axis at the end with np.newaxis/None and then do elementwise multiplication with b, bringing in broadcasting for a vectorized solution, like so -
b*a[...,None]
Sample run -
In [19]: a
Out[19]:
array([[2, 8],
[4, 7],
[1, 2],
[5, 2],
[7, 4]])
In [20]: b
Out[20]: array([3, 5, 5])
In [21]: b*a[...,None]
Out[21]:
array([[[ 6, 10, 10],
[24, 40, 40]],
[[12, 20, 20],
[21, 35, 35]],
[[ 3, 5, 5],
[ 6, 10, 10]],
[[15, 25, 25],
[ 6, 10, 10]],
[[21, 35, 35],
[12, 20, 20]]])