Transposición de matrices en Python


143

Estoy tratando de crear una función de transposición de matriz para Python, pero parece que no puedo hacer que funcione. Di que tengo

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

y quiero que mi función surja

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

En otras palabras, si imprimiera esta matriz 2D como columnas y filas, me gustaría que las filas se convirtieran en columnas y columnas en filas.

Hice esto hasta ahora pero no funciona

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

Respuestas:


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 va a iterar a través de los resultados, izipdesde itertoolspuede ahorrar memoria para matrices grandes.
Antony Hatchkins

¿Cómo le gustaría devolver una lista para las sublistas? Me gusta en [['a', 'b', 'g'], ['d', 'e', 'h'], ['c', 'f', 'i']]lugar de [('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]?
colección_

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

1
@AntonyHatchkins Esto no es necesario con Python 3.0 y superior. Allí, zipya devuelve un iterador: docs.python.org/3.0/whatsnew/…
xuiqzy

1
@xuiqzy No es que no lo sepa, pero es cierto.
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']]

El generador de listas crea una nueva matriz 2D con elementos de lista en lugar de tuplas.


Este es el camino a seguir si desea asignar el resultado a una variable (en lugar de, por ejemplo, iterar sobre ella directamente), suponiendo que desea listas en lugar de tuplas, como se mencionó.
ASL

Otra opción (como lo implican los comentarios en la respuesta aceptada) sería:list(map(list, zip(*theArray)))
ASL

37

Si sus filas no son iguales, también puede usar map:

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

Editar: en Python 3, la funcionalidad de los mapcambios itertools.zip_longestse puede utilizar en su lugar:
Fuente: Novedades de 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

Mucho más fácil 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

El problema con su código original fue que se inicializó transpose[t]en cada elemento, en lugar de solo una vez por fila:

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

Esto funciona, aunque hay más formas pitónicas de lograr las mismas cosas, incluida la zipaplicación de @ JF .


1
Tenga en cuenta que esta implementación no funciona con matrices que tienen diferentes números de columnas y filas
Vector

4

Para completar la respuesta de JF Sebastian, si tienes una lista de listas con diferentes longitudes, mira esta gran publicación de ActiveState . En breve:

La función integrada zip hace un trabajo similar, pero trunca el resultado a la longitud de la lista más corta, por lo que algunos elementos de los datos originales pueden perderse después.

Para manejar la lista de listas con diferentes longitudes, use:

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)

Esa es una buena captura. Sin embargo, las matrices no tienen listas con diferentes longitudes.
Olli

Depende de cómo se almacenan.
Franck Dernoncourt

3

La "mejor" respuesta ya se ha enviado, pero pensé que agregaría que puede usar las comprensiones de listas anidadas, como se ve en el Tutorial de Python .

Así es como podría obtener una matriz transpuesta:

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

1

Éste conservará la forma rectangular, para que las transposiciones posteriores obtengan el resultado correcto:

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

1

puedes probar esto con una lista de comprensión como la siguiente

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 desea transponer una matriz como A = np.array ([[1,2], [3,4]]), simplemente puede usar AT, pero para un vector como a = [1,2], aT no devuelve una transposición! y necesita usar a.reshape (-1, 1), como se muestra a continuación

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

Puedes hacerlo simplemente usando la comprensión de 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]))]

Aunque esta puede ser una respuesta correcta. Dos líneas de código no son muy útiles sin una explicación de qué y cómo resuelve la pregunta original. Proporcione detalles a su respuesta.
RyanNerd

1
Al publicar una nueva respuesta a una pregunta anterior, las expectativas son altas. Por favor, no publique una solución inferior a las ya publicadas
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

Es una implementación simple para una transposición, aunque hay bibliotecas como las mencionadas en otras respuestas que también están disponibles.
Ravneet Singh

-4

``

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

`Esta función devolverá la transposición


-4

Programa Python para transponer matriz:

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
¡Esto no es útil!
Tripulse
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.