Matrix Transpose en Python

143

J'essaie de créer une fonction de transposition de matrice pour python mais je n'arrive pas à la faire fonctionner. Dis que j'ai

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

et je veux que ma fonction vienne avec

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

Donc, en d'autres termes, si je devais imprimer ce tableau 2D sous forme de colonnes et de lignes, je voudrais que les lignes se transforment en colonnes et les colonnes en lignes.

J'ai fait ça jusqu'ici mais ça ne marche pas

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
la source

Réponses:

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
la source
15
si vous allez parcourir les résultats, izipfrom itertoolspeut économiser de la mémoire pour les grands tableaux.
Antony Hatchkins
Comment voudriez-vous qu'il renvoie une liste pour les sous-listes? Comme [['a', 'b', 'g'], ['d', 'e', 'h'], ['c', 'f', 'i']]au lieu de [('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]?
acollection_
13
@acollection_: map(list, zip(*theArray)).
jfs
1
@AntonyHatchkins Cela n'est pas nécessaire avec Python 3.0 et supérieur. Là, ziprenvoie déjà un itérateur: docs.python.org/3.0/whatsnew/…
xuiqzy
1
@xuiqzy Ce n'est pas que je n'en ai pas conscience, mais c'est vrai.
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']]

le générateur de liste crée un nouveau tableau 2d avec des éléments de liste au lieu de tuples.

sqwerl
la source
C'est la voie à suivre si vous voulez affecter le résultat à une variable (par opposition, par exemple, à l'itérer directement) - en supposant que vous vouliez des listes au lieu de tuples, comme mentionné.
ASL
Une autre option (comme le suggèrent les commentaires dans la réponse acceptée) serait:list(map(list, zip(*theArray)))
ASL
37

Si vos lignes ne sont pas égales, vous pouvez également utiliser map:

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

Edit: Dans Python 3, la fonctionnalité de mapchangé itertools.zip_longestpeut être utilisée à la place:
Source: Quoi de neuf dans 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
la source
15

Beaucoup plus facile avec 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
la source
6

Le problème avec votre code d'origine était que vous avez initialisé transpose[t]à chaque élément, plutôt qu'une seule fois par ligne:

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

Cela fonctionne, bien qu'il y ait plus de façons pythoniques d'accomplir les mêmes choses, y compris l' zipapplication de @ JF .

Ned Batchelder
la source
1
Notez que cette implémentation ne fonctionne pas avec des matrices qui ont différents nombres de colonnes et de lignes
Vecteur
4

Pour compléter la réponse de JF Sebastian, si vous avez une liste de listes de différentes longueurs, consultez cet excellent article d'ActiveState . En bref:

La fonction intégrée zip fait un travail similaire, mais tronque le résultat à la longueur de la liste la plus courte, de sorte que certains éléments des données d'origine peuvent être perdus par la suite.

Pour gérer une liste de listes de différentes longueurs, utilisez:

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
la source
C'est une bonne prise. Cependant, les matrices n'ont pas de listes de longueurs différentes.
Olli
Cela dépend de la façon dont ils sont stockés.
Franck Dernoncourt
3

La "meilleure" réponse a déjà été soumise, mais j'ai pensé ajouter que vous pouvez utiliser des compréhensions de listes imbriquées, comme vu dans le didacticiel Python .

Voici comment vous pouvez obtenir un tableau transposé:

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

Celui-ci conservera la forme rectangulaire, de sorte que les transpositions ultérieures obtiendront le bon résultat:

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

vous pouvez essayer ceci avec la compréhension de liste comme suit

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
la source
0

Si vous voulez transposer une matrice comme A = np.array ([[1,2], [3,4]]), alors vous pouvez simplement utiliser AT, mais pour un vecteur comme a = [1,2], aT ne retourne pas une transposition! et vous devez utiliser a.reshape (-1, 1), comme ci-dessous

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
la source
0

Vous pouvez le faire simplement en utilisant la compréhension 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]))]
rasoul poordelan
la source
Bien que cela puisse être une bonne réponse. Deux lignes de code ne sont pas très utiles sans une explication de quoi et comment cela résout la question d'origine. Veuillez fournir des détails sur votre réponse.
RyanNerd le
1
lorsque vous publiez une nouvelle réponse à une ancienne question, les attentes sont élevées. Merci de ne pas poster de solution inférieure à celles déjà postées
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)
Astérisque
la source
-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
la source
-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
la source
-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
la source
-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
la source
C'est une implémentation simple pour une transposition, bien qu'il existe des bibliothèques comme celles mentionnées dans d'autres réponses sont également disponibles.
Ravneet Singh
-4

»

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

`Cette fonction retournera la transposition

user2412711
la source
-4

Programme Python pour transposer la 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(' ')
MK Rana
la source
1
Ce n'est pas utile!
tripulse