Reputation: 65
I'm trying to rotate a 3*3 matrix clockwise 90 degrees in python. I've identified that element at [ i ][ j ] goes to [ j ][ new_i ]. Here new_i depends upon the previous i, so i made a function for it called circular subtraction.
if i is 0 then new_i is 2
if i is 1 then new_i is 1
if i is 2 then new_i is 0
after execution, it gave me unexpected results.
I've printed everything that is happening in each iteration. I am unable to figure out how some elements are getting replaced with different ones.
'''
1 2 3 7 4 1
4 5 6 rotate 90 degrees 8 5 2
7 8 9 9 6 3
'''
def circular_subtraction(i):
new_i = i
if(i==0):
new_i = 2
elif(i==1):
new_i = 1
elif(i==2):
new_i = 0
return new_i
def rotate_clock(matrix):
new_matrix = matrix
for i in range(len(matrix)):
for j in range(len(matrix)):
new_i = circular_subtraction(i)
new_matrix[j][new_i] = matrix[i][j]
print("New element added from {},{} to {},{} ::: {} to {}".format(i+1,j+1,j+1,new_i+1,matrix[i][j],new_matrix[j][new_i]))
for each_row in new_matrix:
print(each_row)
matrix = [[1,2,3],[4,5,6],[7,8,9]]
print("Length of the matrix : ",len(matrix))
for each_row in matrix:
print(each_row)
print()
matrix = rotate_clock(matrix)
the input matrix was
[1, 2, 3]
[4, 5, 6]
[7, 8, 9]
The expected result was:
[7, 4, 1]
[8, 5, 2]
[9, 6, 3]
Result is:
[7, 4, 1]
[2, 5, 2]
[1, 2, 1]
Upvotes: 4
Views: 10504
Reputation: 1
Generally all solution are for square matrix, Below one will for any matrix:
mat = [[1, 2, 3, 5],
[5, 6, 7, 1],
[9, 10, 11, 8],
[4, 7, 4, 3]]
def rotate_matrix(a):
b = []
i = len(a)-1
while i>=0:
if len(a) == len(a[-1]):
for j in range(0, len(a)):
print(j)
if (len(b) < (j+1)):
b.append([a[i][j]])
print(b)
else:
b[j].append(a[i][j])
print(b)
i -= 1
else:
for j in range(0, len(a)+1):
print(j)
if (len(b) < (j+1)):
b.append([a[i][j]])
print(b)
else:
b[j].append(a[i][j])
print(b)
i -= 1
return b
print(rotate_matrix(mat))
Upvotes: 0
Reputation: 1
A simple solution to rotate any matrix would be
import copy
def rotateImage(a):
out = copy.deepcopy(a)
x = 0;
y = 0;
for i in a:
l = len(i)
for j in i:
out[y][x+l-1] = j
y += 1
if(y == l):
y=0
x -= 1
return(out)
Upvotes: 0
Reputation: 491
In very simple python, this code works:
def rotate_matrix(a):
b = []
i = len(a)-1
while i>=0:
for j in range(0, len(a)):
if (len(b) < (j+1)):
b.append([a[i][j]])
else:
b[j].append(a[i][j])
i -= 1
return b
I printed b. That looked like this:
[[7, 4, 1], [8, 5, 2], [9, 6, 3]]
Upvotes: 2
Reputation: 620
You can use the numpy rot90 function for this: np.rot90
mat = [[1, 2, 3], [4,5,6,], [7,8,9]]
np.rot90(mat, k=1, axes=(1,0))
k - indicates number of rotations
axes - indicates the direction of rotation
Output
array([[7, 4, 1],
[8, 5, 2],
[9, 6, 3]])
The code is missing indents (but assuming they are correct)
the line :
new_matrix = matrix
assigns a new reference to the matrix variable.
In python the default isn't copy by value.
You can use deep copy function : copy.deepcopy(x[, memo])
import copy
def rotate_clock(matrix):
new_matrix = copy.deepcopy(matrix)
OR
def rotate_clock(matrix):
new_matrix = [row[:] for row in matrix]
Otherwise, each change you make to new_matrix is being done in the original matrix as well. (since new_matrix is just a reference to matrix)
Upvotes: 5
Reputation: 7585
A general method to rotate the Matrix
, irrespective of shape.
import numpy as np
A=np.array([[1, 2, 3, 33], [4, 5, 6, 66], [7, 8, 9, 99]])
A
array([[ 1, 2, 3, 33],
[ 4, 5, 6, 66],
[ 7, 8, 9, 99]])
rotated_A=np.zeros((len(A[0]),len(A)))
for i in range(len(A)):
for j in range(len(A[0])):
rotated_A[j][len(A)-1-i]=A[i][j]
rotated_A
array([[ 7., 4., 1.],
[ 8., 5., 2.],
[ 9., 6., 3.],
[ 99., 66., 33.]])
Upvotes: 1
Reputation: 4137
numpy.rot90
could come handy as well:
import numpy as np
a = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
a_rot = np.rot90(a, k=3).tolist()
for row in a_rot:
print(row)
Output
[7, 4, 1]
[8, 5, 2]
[9, 6, 3]
Upvotes: 1
Reputation: 61900
You could do something like this:
matrix = [[1, 2, 3],
[4, 5, 6],
[7, 8, 9]]
rotated = [list(reversed(col)) for col in zip(*matrix)]
for row in rotated:
print(*row)
Output
7 4 1
8 5 2
9 6 3
The for col in zip(*matrix)
gets the column of the matrix, once you have the columns you need to reverse them using list(reversed(col))
, then use a list comprehension to put all together:
rotated = [list(reversed(col)) for col in zip(*matrix)]
The above list comprehension is equivalent to the following less pythonic for loop:
rotated = []
for col in zip(*matrix):
rotated.append(list(reversed(col)))
Further
*matrix
is known as tuple unpacking, more here.Upvotes: 10