Matrix Transponieren in Python

142

Ich versuche, eine Matrix-Transponierungsfunktion für Python zu erstellen, aber ich kann nicht scheinen, dass es funktioniert. Sag ich habe

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

und ich möchte, dass meine Funktion erfüllt wird

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

Mit anderen Worten, wenn ich dieses 2D-Array als Spalten und Zeilen drucken würde, möchte ich, dass die Zeilen in Spalten und Spalten in Zeilen umgewandelt werden.

Ich habe das bisher gemacht, aber es funktioniert nicht

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
Julio Diaz
quelle

Antworten:

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')]
jfs
quelle
15
wenn Sie durchlaufen die Ergebnisse gehen, izipvon itertoolssparen können Speicher für große Arrays.
Antony Hatchkins
Wie soll eine Liste für die Unterlisten zurückgegeben werden? Wie [['a', 'b', 'g'], ['d', 'e', 'h'], ['c', 'f', 'i']]statt [('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]?
acollection_
13
@acollection_ : map(list, zip(*theArray)).
JFS
1
@AntonyHatchkins Dies wird mit Python 3.0 und höher nicht benötigt. Dort wird zipbereits ein Iterator zurückgegeben: docs.python.org/3.0/whatsnew/…
xuiqzy
1
@xuiqzy Es ist nicht so, dass ich mir dessen nicht bewusst bin, aber das stimmt.
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']]

Der Listengenerator erstellt ein neues 2D-Array mit Listenelementen anstelle von Tupeln.

sqwerl
quelle
Dies ist der richtige Weg, wenn Sie das Ergebnis einer Variablen zuweisen möchten (anstatt z. B. direkt darüber zu iterieren) - vorausgesetzt, Sie möchten Listen anstelle von Tupeln, wie erwähnt.
ASL
Eine andere Option (wie durch die Kommentare in der akzeptierten Antwort impliziert) wäre:list(map(list, zip(*theArray)))
ASL
37

Wenn Ihre Zeilen nicht gleich sind, können Sie auch Folgendes verwenden map:

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

Bearbeiten: In Python 3 kann stattdessen die mapgeänderte Funktionalität itertools.zip_longestverwendet werden:
Quelle: Was ist neu in 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')]
Bigjim
quelle
15

Viel einfacher mit 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')
Irshad Bhat
quelle
6

Das Problem mit Ihrem ursprünglichen Code war, dass Sie transpose[t]bei jedem Element und nicht nur einmal pro Zeile initialisiert haben :

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

Dies funktioniert, obwohl es mehr pythonische Möglichkeiten gibt, um die gleichen Dinge zu erreichen, einschließlich der zipAnwendung von @ JF .

Ned Batchelder
quelle
1
Beachten Sie, dass diese Implementierung nicht mit Matrizen funktioniert, die eine unterschiedliche Anzahl von Spalten und Zeilen haben
Vector
4

Wenn Sie eine Liste mit Listen unterschiedlicher Länge haben, lesen Sie diesen großartigen Beitrag von ActiveState , um die Antwort von JF Sebastian zu vervollständigen . Zusamenfassend:

Die integrierte Funktion zip erledigt einen ähnlichen Job, schneidet das Ergebnis jedoch auf die Länge der kürzesten Liste ab, sodass einige Elemente aus den Originaldaten später verloren gehen können.

Verwenden Sie Folgendes, um eine Liste mit Listen unterschiedlicher Länge zu erstellen:

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)
Franck Dernoncourt
quelle
Das ist ein guter Fang. Matrizen haben jedoch keine Listen mit unterschiedlichen Längen.
Olli
Es hängt davon ab, wie sie gespeichert werden.
Franck Dernoncourt
3

Die "beste" Antwort wurde bereits übermittelt, aber ich dachte, ich würde hinzufügen, dass Sie verschachtelte Listenverständnisse verwenden können, wie im Python-Tutorial gezeigt .

So können Sie ein transponiertes Array erhalten:

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

Dieser behält die rechteckige Form bei, so dass nachfolgende Transponierungen das richtige Ergebnis erzielen:

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

Sie können dies mit Listenverständnis wie folgt versuchen

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)

sharif_42
quelle
0

Wenn Sie eine Matrix wie A = np.array ([[1,2], [3,4]]) transponieren möchten, können Sie einfach AT verwenden, aber für einen Vektor wie a = [1,2], aT gibt keine Transponierte zurück! und Sie müssen a.reshape (-1, 1) wie unten verwenden

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)
Hassan Bahaloo
quelle
0

Sie können dies einfach mit Python-Verständnis tun.

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]))]
rasoul poordelan
quelle
Obwohl dies eine richtige Antwort sein kann. Zwei Codezeilen sind ohne eine Erklärung, was und wie die ursprüngliche Frage gelöst wird, nicht sehr nützlich. Bitte geben Sie Details zu Ihrer Antwort an.
RyanNerd
1
Wenn Sie eine neue Antwort auf eine alte Frage veröffentlichen, sind die Erwartungen hoch. Bitte veröffentlichen Sie keine schlechtere Lösung als die bereits veröffentlichten
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)
Sternchen
quelle
-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'
roo.firebolt
quelle
-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)
Chaitanya
quelle
-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
mohammad hassan jafari
quelle
-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
Ravneet Singh
quelle
Es ist eine einfache Implementierung für eine Transponierung, obwohl es Bibliotheken gibt, wie in anderen Antworten erwähnt, die ebenfalls verfügbar sind.
Ravneet Singh
-4

`

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

`Diese Funktion gibt die Transponierte zurück

user2412711
quelle
-4

Python-Programm zur Transponierung der Matrix:

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(' ')
MK Rana
quelle
1
Das ist nicht sinnvoll!
Tripulse