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

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')]

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.


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')]

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')

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 .


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)

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 ] ) ) ]

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=' '))

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)


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)

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]))]

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)

-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

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


-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(' ')

1
Ce n'est pas utile!
tripulse
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.