Matrix Transpose in Python


143

Sto cercando di creare una funzione di trasposizione matrice per Python ma non riesco a farlo funzionare. Di 'che ho

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

e voglio che la mia funzione venga fuori

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

Quindi, in altre parole, se dovessi stampare questo array 2D come colonne e righe, vorrei che le righe si trasformassero in colonne e colonne in righe.

L'ho fatto finora ma non funziona

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

Risposte:


308

Python 2:

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

Python 3:

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

15
se si sta andando per scorrere i risultati, izipdal itertoolspossibile risparmiare memoria per grandi array.
Antony Hatchkins,

Come vorresti che restituisse un elenco per gli elenchi secondari? Come [['a', 'b', 'g'], ['d', 'e', 'h'], ['c', 'f', 'i']]invece di [('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]?
acollection_

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

1
@AntonyHatchkins Questo non è necessario con Python 3.0 e versioni successive. Lì, ziprestituisce già un iteratore: docs.python.org/3.0/whatsnew/…
xuiqzy

1
@xuiqzy Non è che non ne sia consapevole, ma è vero.
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']]

il generatore di elenchi crea un nuovo array 2d con voci di elenco anziché tuple.


Questa è la strada da percorrere se si desidera assegnare il risultato a una variabile (al contrario, ad esempio, iterando direttamente su di esso) - supponendo che si desideri elenchi anziché tuple, come menzionato.
ASL

Un'altra opzione (come suggerito dai commenti nella risposta accettata) sarebbe:list(map(list, zip(*theArray)))
ASL

37

Se le tue righe non sono uguali puoi anche usare map:

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

Modifica: In Python 3 è invece possibile utilizzare la funzionalità di mapmodificata itertools.zip_longest:
Fonte: Novità di 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

Molto più facile con 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

Il problema con il codice originale era che hai inizializzato transpose[t]su ogni elemento, piuttosto che una sola volta per riga:

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

Funziona, anche se ci sono altri modi Pythonic per realizzare le stesse cose, inclusa l' zipapplicazione di @ JF .


1
Nota che questa implementazione non funziona con matrici che hanno un numero diverso di colonne e righe
Vector

4

Per completare la risposta di JF Sebastian, se hai un elenco di liste con lunghezze diverse, dai un'occhiata a questo fantastico post di ActiveState . In breve:

La funzione zip integrata svolge un lavoro simile, ma tronca il risultato alla lunghezza dell'elenco più breve, quindi alcuni elementi dei dati originali potrebbero andare persi in seguito.

Per gestire un elenco di elenchi con lunghezze diverse, utilizzare:

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)

È una buona cattura. Tuttavia, le matrici non hanno elenchi con lunghezze diverse.
Olli,

Dipende da come sono memorizzati.
Franck Dernoncourt,

3

La risposta "migliore" è già stata inviata, ma ho pensato di aggiungere che puoi usare la comprensione dell'elenco nidificato, come mostrato nel tutorial di Python .

Ecco come è possibile ottenere un array trasposto:

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

1

Questo manterrà la forma rettangolare, in modo che i successivi recepimenti ottengano il giusto risultato:

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

1

puoi provarlo con la comprensione dell'elenco come il seguente

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

Se vuoi trasporre una matrice come A = np.array ([[1,2], [3,4]]), puoi semplicemente usare AT, ma per un vettore come a = [1,2], aT non restituisce una trasposizione! e devi usare a.reshape (-1, 1), come di seguito

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

Puoi farlo semplicemente usando la comprensione di 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]))]

Anche se questa potrebbe essere una risposta corretta. Due righe di codice non sono molto utili senza una spiegazione di cosa e come risolve la domanda originale. Fornisci i dettagli della tua risposta.
RyanNerd,

1
quando si pubblica una nuova risposta a una vecchia domanda, le aspettative sono alte. Per favore, non pubblicare una soluzione inferiore a quelle già pubblicate
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

È una semplice implementazione per un recepimento, sebbene siano disponibili anche librerie come quelle menzionate in altre risposte.
Ravneet Singh,

-4

`

def transpose(m):
    return(list(map(list,list(zip(*m)))))

`Questa funzione restituirà la trasposizione


-4

Programma Python per trasporre matrice:

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
Questo non è utile!
tripulse
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.