Home > Mobile >  Assign indexes to rotated indexes
Assign indexes to rotated indexes

Time:01-02

I have a (3, 2, 2) array whose three 2D subarrays I want to rotate without loops by 0°, 90°, and 180°, respectively:

import numpy as np
import matplotlib.pyplot as plt

arr = np.array([[[2,3],
                 [3,3]],
                
                [[4,5],
                 [5,5]],
                
                [[6,7],
                 [7,7]]])

for k in np.arange(3):
    plt.imshow(arr[k,:,:], cmap='gray', vmin=2, vmax=7)
    plt.show()

Therefore, I defined two (3, 2, 2) arrays containing the x and y indices...

x_ = np.array([[[0,1],
                [0,1]],
                
               [[0,1],
                [0,1]],
                
               [[0,1],
                [0,1]]]) 

y_ = np.array([[[0,0],
                [1,1]],
                
               [[0,0],
                [1,1]],
                
               [[0,0],
                [1,1]]])

... and rotated them:

x_rot = np.array([[[0,1],
                   [0,1]],
                
                  [[1,1],
                   [0,0]],
                
                  [[1,0],
                   [1,0]]]) 

y_rot = np.array([[[0,0],
                   [1,1]],
                 
                  [[0,1],
                   [0,1]],
                
                  [[1,1],
                   [0,0]]])

But I don't understand why the following index assignment doesn't work, because instead each 2D subarray is rotated 180°:

arr_rot = np.zeros((3, 2, 2), dtype=int)
arr_rot[:, x_, y_] = arr[:, x_rot, y_rot]

for k in np.arange(3):
    plt.imshow(arr_rot[k,:,:], cmap='gray', vmin=2, vmax=7)
    plt.show()

CodePudding user response:

It looks like the issue is with the indexing. When you use arr_rot[:, x_, y_] = arr[:, x_rot, y_rot], you are assigning values to the indices specified by x_ and y_ in arr_rot using the values at indices specified by x_rot and y_rot in arr.

To rotate the 2D subarrays in arr by 0°, 90°, and 180° and assign the resulting rotated subarrays to arr_rot, you can use a combination of slicing and indexing.


import numpy as np
import matplotlib.pyplot as plt

Next, we define the (3, 2, 2) array arr:

arr = np.array([[[2,3],
                 [3,3]],
                
                [[4,5],
                 [5,5]],
                
                [[6,7],
                 [7,7]]])

Then create a new (3, 2, 2) array arr_rot filled with zeros using NumPy's zeros() function:

arr_rot = np.zeros((3, 2, 2), dtype=int)

rotate the 2D subarrays in arr and assign the resulting rotated subarrays to arr_rot using a combination of slicing and indexing:

# Rotate the first 2D subarray by 0°
arr_rot[0,:,:] = arr[0,:,:]

# Rotate the second 2D subarray by 90°
arr_rot[1,:,:] = arr[1,::-1,:].T

# Rotate the third 2D subarray by 180°
arr_rot[2,:,:] = arr[2,::-1,::-1]

The for loop iterates over the three 2D subarrays in arr_rot, and the imshow() function plots each subarray in a separate window.

# Plot the rotated 2D subarrays
for k in np.arange(3):
    plt.imshow(arr_rot[k,:,:], cmap='gray', vmin=2, vmax=7)
    plt.show()

Whole Code :

import numpy as np
import matplotlib.pyplot as plt

arr = np.array([[[2,3],
                 [3,3]],
                
                [[4,5],
                 [5,5]],
                
                [[6,7],
                 [7,7]]])

arr_rot = np.zeros((3, 2, 2), dtype=int)

# Rotate the first 2D subarray by 0°
arr_rot[0,:,:] = arr[0,:,:]

# Rotate the second 2D subarray by 90°
arr_rot[1,:,:] = arr[1,::-1,:].T

# Rotate the third 2D subarray by 180°
arr_rot[2,:,:] = arr[2,::-1,::-1]

# Plot the rotated 2D subarrays
for k in np.arange(3):
    plt.imshow(arr_rot[k,:,:], cmap='gray', vmin=2, vmax=7)
    plt.show()

CodePudding user response:

You were already really close: you can get the desired result using x_rot and y_rot by also indexing the first dimension:

out = arr[np.arange(3)[:, None, None], x_rot, y_rot]

out:

array([[[2, 3],
        [3, 3]],

       [[5, 5],
        [4, 5]],

       [[7, 7],
        [7, 6]]])

CodePudding user response:

Thank you, W.A, for your detailed and understandable answer.

Sorry, I should have mentioned that I should program flexibly: arr can be any (T, M, M) array and the T angles are given arbitrarily. So my code so far looks like this:

import numpy as np
import matplotlib.pyplot as plt

arr = np.array([[[2,3],
                 [3,3]],
                
                [[4,5],
                 [5,5]],
                
                [[6,7],
                 [7,7]]])

M = 2
T = 3
b = 2*np.pi
angles = np.array([np.linspace(0, (T-1)*b/T, T)]).T

# create indices arrays
x_ = np.tile(np.arange(M), (M, 1)).
y_ = np.tile(np.arange(M), (M, 1)).T
x_, y_ = np.repeat(x_, T, axis=0), np.tile(y_, (T, 1))
x_, y_ = x_.reshape((T, M, M)), y_.reshape((T, M, M))

# center, rotate and decenter 2D subarrays
center = -M/2   0.5
decenter = -center 

x_rot = ((x_   center)*np.cos(angles) - (y_   center)*np.sin(angles))   decenter
y_rot = ((x_   center)*np.sin(angles)   (y_   center)*np.cos(angles))   decenter

# set indices that lie outside 0...(M-1) equal to zero.
x_rot[(x_rot < 0)   (x_rot > M-1)] = 0
y_rot[(y_rot < 0)   (y_rot > M-1)] = 0

arr_rot = np.zeros((T, M, M), dtype=int)
arr_rot[:, x_, y_] = arr[:, x_rot.astype(int), y_rot.astype(int)]
  • Related