Ma trận chuyển vị trong Python


142

Tôi đang cố gắng tạo một hàm hoán vị ma trận cho python nhưng dường như tôi không thể làm cho nó hoạt động được. Nói tôi có

theArray = [['a','b','c'],['d','e','f'],['g','h','i']]

và tôi muốn chức năng của mình được đưa ra

newArray = [['a','d','g'],['b','e','h'],['c', 'f', 'i']]

Vì vậy, nói cách khác, nếu tôi in mảng 2D này dưới dạng cột và hàng, tôi muốn các hàng biến thành cột và cột thành hàng.

Tôi đã làm điều này cho đến nay nhưng nó không hoạt động

def matrixTranspose(anArray):
    transposed = [None]*len(anArray[0])
    for t in range(len(anArray)):
        for tt in range(len(anArray[t])):
            transposed[t] = [None]*len(anArray)
            transposed[t][tt] = anArray[tt][t]
    print transposed

Câu trả lời:


308

Con trăn 2:

>>> theArray = [['a','b','c'],['d','e','f'],['g','h','i']]
>>> zip(*theArray)
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]

Con trăn 3:

>>> [*zip(*theArray)]
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]

15
nếu bạn định lặp lại kết quả, iziptừ đó itertoolscó thể lưu bộ nhớ cho các mảng lớn.
Antony Hatchkins

Làm thế nào bạn có nó trả lại một danh sách cho danh sách phụ? Thích [['a', 'b', 'g'], ['d', 'e', 'h'], ['c', 'f', 'i']]thay [('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]?
acollection_

13
@acollection_ : map(list, zip(*theArray)).
jfs

1
@AntonyHatchkins Điều này không cần thiết với Python 3.0 trở lên. Ở đó, zipđã trả về một iterator: docs.python.org/3.0/whatsnew/...
xuiqzy

1
@xuiqzy Không phải tôi không biết, nhưng đó là sự thật.
Antony hatchkins

64
>>> theArray = [['a','b','c'],['d','e','f'],['g','h','i']]
>>> [list(i) for i in zip(*theArray)]
[['a', 'd', 'g'], ['b', 'e', 'h'], ['c', 'f', 'i']]

trình tạo danh sách tạo ra một mảng 2d mới với các mục danh sách thay vì các bộ dữ liệu.


Đây là cách để đi nếu bạn muốn gán kết quả cho một biến (trái ngược với, ví dụ, lặp lại trực tiếp trên nó) - giả sử bạn muốn danh sách thay vì bộ dữ liệu, như đã đề cập.
ASL

Một lựa chọn khác (theo ngụ ý của các ý kiến ​​trong câu trả lời được chấp nhận) sẽ là:list(map(list, zip(*theArray)))
ASL

37

Nếu các hàng của bạn không bằng nhau, bạn cũng có thể sử dụng map:

>>> uneven = [['a','b','c'],['d','e'],['g','h','i']]
>>> map(None,*uneven)
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', None, 'i')]

Chỉnh sửa: Trong Python 3 chức năng mapthay đổi, itertools.zip_longestcó thể được sử dụng thay thế:
Nguồn: Có gì mới trong Python 3.0

>>> import itertools
>>> uneven = [['a','b','c'],['d','e'],['g','h','i']]
>>> list(itertools.zip_longest(*uneven))
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', None, 'i')]

15

Dễ dàng hơn nhiều với numpy:

>>> arr = np.array([[1,2,3],[4,5,6],[7,8,9]])
>>> arr
array([[1, 2, 3],
       [4, 5, 6],
       [7, 8, 9]])
>>> arr.T
array([[1, 4, 7],
       [2, 5, 8],
       [3, 6, 9]])
>>> theArray = np.array([['a','b','c'],['d','e','f'],['g','h','i']])
>>> theArray 
array([['a', 'b', 'c'],
       ['d', 'e', 'f'],
       ['g', 'h', 'i']], 
      dtype='|S1')
>>> theArray.T
array([['a', 'd', 'g'],
       ['b', 'e', 'h'],
       ['c', 'f', 'i']], 
      dtype='|S1')

6

Vấn đề với mã ban đầu của bạn là bạn đã khởi tạo transpose[t]ở mọi phần tử, thay vì chỉ một lần mỗi hàng:

def matrixTranspose(anArray):
    transposed = [None]*len(anArray[0])
    for t in range(len(anArray)):
        transposed[t] = [None]*len(anArray)
        for tt in range(len(anArray[t])):
            transposed[t][tt] = anArray[tt][t]
    print transposed

Điều này hoạt động, mặc dù có nhiều cách Pythonic hơn để thực hiện những điều tương tự, bao gồm cả zipứng dụng của @ JF .


1
Lưu ý rằng việc triển khai này không hoạt động với các ma trận có số lượng cột và hàng khác nhau
Vector

4

Để hoàn thành câu trả lời của JF Sebastian, nếu bạn có một danh sách các danh sách với độ dài khác nhau, hãy xem bài đăng tuyệt vời này từ ActiveState . Nói ngắn gọn:

Hàm zip tích hợp thực hiện một công việc tương tự, nhưng cắt ngắn kết quả theo độ dài của danh sách ngắn nhất, do đó một số phần tử từ dữ liệu gốc có thể bị mất sau đó.

Để xử lý danh sách các danh sách có độ dài khác nhau, hãy sử dụng:

def transposed(lists):
   if not lists: return []
   return map(lambda *row: list(row), *lists)

def transposed2(lists, defval=0):
   if not lists: return []
   return map(lambda *row: [elem or defval for elem in row], *lists)

Đó là bắt tốt. Tuy nhiên, ma trận không có danh sách với độ dài khác nhau.
Olli

Nó phụ thuộc vào cách chúng được lưu trữ.
Franck Dernoncourt

3

Câu trả lời "tốt nhất" đã được gửi, nhưng tôi nghĩ tôi sẽ thêm rằng bạn có thể sử dụng các cách hiểu danh sách lồng nhau, như đã thấy trong Hướng dẫn Python .

Đây là cách bạn có thể có được một mảng chuyển:

def matrixTranspose( matrix ):
    if not matrix: return []
    return [ [ row[ i ] for row in matrix ] for i in range( len( matrix[ 0 ] ) ) ]

1

Cái này sẽ giữ hình dạng hình chữ nhật, để các lần chuyển tiếp theo sẽ có kết quả đúng:

import itertools
def transpose(list_of_lists):
  return list(itertools.izip_longest(*list_of_lists,fillvalue=' '))

1

bạn có thể thử điều này với việc hiểu danh sách như sau

matrix = [['a','b','c'],['d','e','f'],['g','h','i']] n = len(matrix) transpose = [[row[i] for row in matrix] for i in range(n)] print (transpose)


0

Nếu bạn muốn hoán chuyển một ma trận như A = np.array ([[1,2], [3,4]]), thì bạn có thể chỉ cần sử dụng AT, nhưng đối với một vectơ như a = [1,2], aT không trả lại một chuyển vị! và bạn cần sử dụng a.reshape (-1, 1), như dưới đây

import numpy as np
a = np.array([1,2])
print('a.T not transposing Python!\n','a = ',a,'\n','a.T = ', a.T)
print('Transpose of vector a is: \n',a.reshape(-1, 1))

A = np.array([[1,2],[3,4]])
print('Transpose of matrix A is: \n',A.T)

0

Bạn có thể làm điều đó chỉ đơn giản bằng cách sử dụng sự hiểu biết python.

arr = [
    ['a', 'b', 'c'], 
    ['d', 'e', 'f'], 
    ['g', 'h', 'i']
]
transpose = [[arr[y][x] for y in range(len(arr))] for x in range(len(arr[0]))]

Mặc dù đây có thể là một câu trả lời đúng. Hai dòng mã không hữu ích nếu không có lời giải thích về điều gì và cách giải quyết câu hỏi ban đầu. Vui lòng cung cấp chi tiết cho câu trả lời của bạn.
RyanNerd

1
Khi đăng một câu trả lời mới cho một câu hỏi cũ, kỳ vọng rất cao. Xin đừng đăng một giải pháp kém hơn cho những giải pháp đã được đăng
Jean-François Fabre

-1
def matrixTranspose(anArray):
  transposed = [None]*len(anArray[0])

  for i in range(len(transposed)):
    transposed[i] = [None]*len(transposed)

  for t in range(len(anArray)):
    for tt in range(len(anArray[t])):            
        transposed[t][tt] = anArray[tt][t]
  return transposed

theArray = [['a','b','c'],['d','e','f'],['g','h','i']]

print matrixTranspose(theArray)

-3
#generate matrix
matrix=[]
m=input('enter number of rows, m = ')
n=input('enter number of columns, n = ')
for i in range(m):
    matrix.append([])
    for j in range(n):
        elem=input('enter element: ')
        matrix[i].append(elem)

#print matrix
for i in range(m):
    for j in range(n):
        print matrix[i][j],
    print '\n'

#generate transpose
transpose=[]
for j in range(n):
    transpose.append([])
    for i in range (m):
        ent=matrix[i][j]
        transpose[j].append(ent)

#print transpose
for i in range (n):
    for j in range (m):
        print transpose[i][j],
    print '\n'

-4
a=[]
def showmatrix (a,m,n):
    for i in range (m):
        for j in range (n):
            k=int(input("enter the number")
            a.append(k)      
print (a[i][j]),

print('\t')


def showtranspose(a,m,n):
    for j in range(n):
        for i in range(m):
            print(a[i][j]),
        print('\t')

a=((89,45,50),(130,120,40),(69,79,57),(78,4,8))
print("given matrix of order 4x3 is :")
showmatrix(a,4,3)


print("Transpose matrix is:")
showtranspose(a,4,3)

-4
def transpose(matrix):
   x=0
   trans=[]
   b=len(matrix[0])
   while b!=0:
       trans.append([])
       b-=1
   for list in matrix:
       for element in list:
          trans[x].append(element)
          x+=1
       x=0
   return trans

-4
def transpose(matrix):
    listOfLists = []
    for row in range(len(matrix[0])):
        colList = []
        for col in range(len(matrix)):
            colList.append(matrix[col][row])
    listOfLists.append(colList)

    return listOfLists

Đây là một triển khai đơn giản cho một chuyển vị, mặc dù có những thư viện như được đề cập trong các câu trả lời khác cũng có sẵn.
Ravneet Singh


-4

Chương trình Python chuyển ma trận:

row,col = map(int,input().split())
matrix = list()

for i in range(row):
    r = list(map(int,input().split()))
    matrix.append(r)

trans = [[0 for y in range(row)]for x in range(col)]

for i in range(len(matrix[0])):
    for j in range(len(matrix)):
        trans[i][j] = matrix[j][i]     

for i in range(len(trans)):
    for j in range(len(trans[0])):
        print(trans[i][j],end=' ')
    print(' ')

1
Điều này không hữu ích!
ba
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.