2011-11-10 162 views
8

tôi có ma trận 6x6 làm danh sách các danh sách trong python. Ma trận được chia thành 4 khối vuông có kích thước 3x3. Tôi muốn có một cách để chuyển đổi chỉ 1 khối. Tôi có thể làm điều đó bằng cách sử dụng phương pháp truyền thống đi qua từng phần tử và sao chép nó vào mảng khác và ngược lại, nhưng tôi muốn xem liệu có cách nào tốt hơn không, (transposing ma trận trong python có thể được thực hiện trong một dòng bằng cách sử dụng phương pháp zip)chuyển vị/xoay một khối ma trận trong python

cho ví dụ này là đại diện của ma trận và các khối của nó

block 1 block 2 
+-------+-------+ 
| . . . | . . . | 
| . . 2 | 1 . . | 
| . . . | . . . | 
+-------+-------+ 
| . . . | . . . | 
| . . . | . . . | 
| . 1 . | . . . | 
+-------+-------+ 
block 3 block 4 

và xoay (3, bên phải) nên kết quả trong này

block 1 block 2 
+-------+-------+ 
| . . . | . . . | 
| . . 2 | 1 . . | 
| . . . | . . . | 
+-------+-------+ 
| . . . | . . . | 
| 1 . . | . . . | 
| . . . | . . . | 
+-------+-------+ 
block 3 block 4 

tôi muốn tìm một phương pháp có số khối và chỉ xoay khối đó sang trái hoặc sang phải . Có cách nào dễ dàng để làm điều đó không?

+1

Hoạt động có nên được thực hiện không? –

+0

có, Cần phải có tại chỗ, hoặc ít nhất, kết quả cần phải được viết lại cho ma trận gốc – randomThought

Trả lời

5

xây dựng trên ý tưởng Sven Marnach để sử dụng np.rot90, đây là một phiên bản mà xoay góc phần tư chiều kim đồng hồ (theo yêu cầu?). Trong bước quan trọng

block3[:] = np.rot90(block3.copy(),-1) 

một copy() được sử dụng ở bên phải (RHS). Không có copy(), vì các giá trị được gán cho block3, dữ liệu cơ bản được sử dụng trên RHS cũng được thay đổi. Điều này làm lộn xộn các giá trị được sử dụng trong các nhiệm vụ phụ. Không có copy(), nhiều giá trị giống nhau sẽ được trải rộng khoảng block3.

Tôi không thấy cách thực hiện thao tác này mà không có bản sao.

import numpy as np 
a = np.arange(36).reshape(6, 6) 
print(a) 
# [[ 0 1 2 3 4 5] 
# [ 6 7 8 9 10 11] 
# [12 13 14 15 16 17] 
# [18 19 20 21 22 23] 
# [24 25 26 27 28 29] 
# [30 31 32 33 34 35]] 
block3 = a[3:6, 0:3] 

# To rotate counterclockwise 
block3[:] = np.rot90(block3.copy()) 
print(a) 
# [[ 0 1 2 3 4 5] 
# [ 6 7 8 9 10 11] 
# [12 13 14 15 16 17] 
# [20 26 32 21 22 23] 
# [19 25 31 27 28 29] 
# [18 24 30 33 34 35]] 

# To rotate clockwise 
a = np.arange(36).reshape(6, 6) 
block3 = a[3:6, 0:3] 
block3[:] = np.rot90(block3.copy(),-1) 
print(a) 
# [[ 0 1 2 3 4 5] 
# [ 6 7 8 9 10 11] 
# [12 13 14 15 16 17] 
# [30 24 18 21 22 23] 
# [31 25 19 27 28 29] 
# [32 26 20 33 34 35]] 
0

Nó sẽ là một giải pháp để xác định ma trận làm từ điển của các khối và một khối như một danh sách các danh sách? Trong ví dụ của bạn (thay thế transpose() với chức năng bạn sử dụng để transpose nó):

Matrix={1:block1,2:block2,3:block3,4:block4} 
block3=transpose(block3) 
Matrix[3]=block3 
+0

không thực sự vì tôi cần thực hiện các phép toán ma trận khác mà cấu trúc này sẽ không cho phép hoặc sẽ phức tạp hơn. – randomThought

0

Dưới đây là một phương pháp để xoay một "Chặn" từ ma trận bạn đã cung cấp:

matrix = [[0,1,2],[3,4,5],[6,7,8]] 

def rotate(m, right): 
    rm = [] 
    for i in range(0,len(m)): 
     if right: 
      rm.append([row[i] for row in reversed(m)]) 
     else: 
      rm.append([row[i] for row in m]) 
    return rm 

right là một Bool
này sẽ trả về một list of lists

bạn cũng có thể sử dụng:

def rotate(m, right): 
    if right: 
     return list(zip(*reversed(m))) 
    else: 
     return list(zip(*m)) 

nhưng điều này sẽ trả về một EDIT list of tuples


:

Nếu chúng ta đang nói về một ma trận của các loại:

matrix = [[[1,2,3],[4,5,6],[7,8,9]], # block 1 
      [[1,2,3],[4,5,6],[7,8,9]], # block 2 
      [[1,2,3],[4,5,6],[7,8,9]], # block 3 
      [[1,2,3],[4,5,6],[7,8,9]] # block 4 
     ] 

bạn sẽ truy cập vào khối 3 bằng cách sử dụng matrix[2]

do đó, vui chơi xoay ction sẽ được sử dụng như:
rotate(matrix[2], True) #rotate block 3, right

+0

có. toàn bộ ma trận một danh sách các danh sách các số. – randomThought

+0

Danh sách các số là ma trận mà tôi đã cung cấp trong ví dụ, nếu danh sách danh sách các số, bạn có thể chọn khối thứ 3 bằng cách đơn giản là 'xoay (ma trận [2], Đúng/Sai)' – Serdalis

+0

nhưng làm thế nào để bạn trích xuất chỉ khối để vượt qua nó vào chức năng? – randomThought

4

Đối với những gì nó có giá trị, đây là cách đơn giản này ở trong NumPy:

>>> a = numpy.arange(36).reshape(6, 6) 
>>> a 
array([[ 0, 1, 2, 3, 4, 5], 
     [ 6, 7, 8, 9, 10, 11], 
     [12, 13, 14, 15, 16, 17], 
     [18, 19, 20, 21, 22, 23], 
     [24, 25, 26, 27, 28, 29], 
     [30, 31, 32, 33, 34, 35]]) 
>>> block3 = a[3:6, 0:3] 
>>> block3[:] = numpy.rot90(block3, 1).copy() 
>>> a 
array([[ 0, 1, 2, 3, 4, 5], 
     [ 6, 7, 8, 9, 10, 11], 
     [12, 13, 14, 15, 16, 17], 
     [20, 26, 32, 21, 22, 23], 
     [26, 25, 31, 27, 28, 29], 
     [20, 26, 20, 33, 34, 35]]) 
+0

+1 cho numpy.rot90. Tuy nhiên, lưu ý rằng việc sao chép phía bên tay phải sang 'block3 [:]' tại chỗ có tác dụng phụ không thể xóa được - vì các giá trị mới được gán cho 'block3', các giá trị cơ bản ở phía bên tay phải cũng bị ghi đè, để lại nhiều bản sao có cùng giá trị trong kết quả. – unutbu

+0

@unutbu: Cảm ơn bạn đã chỉ ra điều này. Tôi thậm chí không nhìn vào kết quả - tôi chắc chắn 'numpy.rot90()' đang trả về một mảng mới, không phải là một khung nhìn. –

Các vấn đề liên quan