简体   繁体   English

使用python中的列表矩阵顺时针旋转90度

[英]matrix 90 degree clockwise rotation using list in python

I'm trying to rotate a 3*3 matrix clockwise 90 degrees in python.我正在尝试在 python 中将 3*3 矩阵顺时针旋转 90 度。 I've identified that element at [ i ][ j ] goes to [ j ][ new_i ].我已经确定 [i][j] 处的元素转到 [j][new_i]。 Here new_i depends upon the previous i, so i made a function for it called circular subtraction.这里 new_i 依赖于前面的 i,所以我为它做了一个函数,叫做循环减法。

if i is 0 then new_i is 2如果 i 为 0,则 new_i 为 2

if i is 1 then new_i is 1如果 i 为 1,则 new_i 为 1

if i is 2 then new_i is 0如果 i 是 2 那么 new_i 是 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]

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: for col in zip(*matrix)获取矩阵的列,一旦有了需要使用list(reversed(col))反转它们的列,然后使用列表推导将所有内容放在一起:

rotated = [list(reversed(col)) for col in zip(*matrix)]

The above list comprehension is equivalent to the following less pythonic for loop:上面的列表推导等效于以下较少的Pythonic for 循环:

rotated = []
for col in zip(*matrix):
    rotated.append(list(reversed(col)))

Further更远

  1. Documentation on zip , reversed and list .关于zipreversedlist的文档。
  2. The notation *matrix is known as tuple unpacking, more here .符号*matrix被称为元组解包,更多信息在这里

You can use the numpy rot90 function for this: np.rot90您可以为此使用 numpy rot90 函数: 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 k - 表示旋转次数
axes - indicates the direction of rotation轴 - 指示旋转方向

Output输出

array([[7, 4, 1],
   [8, 5, 2],
   [9, 6, 3]])

The issue in your code您的代码中的问题

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.在 python 中,默认值不是按值复制。 You can use deep copy function : copy.deepcopy(x[, memo])您可以使用深拷贝功能: 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.否则,您对 new_matrix 所做的每次更改也会在原始矩阵中完成。 (since new_matrix is just a reference to matrix) (因为 new_matrix 只是对矩阵的引用)

In very simple python, this code works:在非常简单的 python 中,此代码有效:

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.我打印了 b。 That looked like this: [[7, 4, 1], [8, 5, 2], [9, 6, 3]]看起来像这样: [[7, 4, 1], [8, 5, 2], [9, 6, 3]]

numpy.rot90 could come handy as well: numpy.rot90也可以派上用场:

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]

A general method to rotate the Matrix , irrespective of shape.一种旋转Matrix的通用方法,与形状无关。

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.]])

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)

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))

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM