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

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')]
jfs
fuente
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.

sqwerl
fuente
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')]
bigjim
fuente
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')
Irshad Bhat
fuente
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 .

Ned Batchelder
fuente
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)
Franck Dernoncourt
fuente
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 ] ) ) ]
leetNightshade
fuente
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=' '))
Vanuan
fuente
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)

sharif_42
fuente
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)
Hassan Bahaloo
fuente
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]))]
rasoul poordelan
fuente
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)
Asterisco
fuente
-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
fuente
-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
fuente
-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
fuente
-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
fuente
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

usuario2412711
fuente
-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(' ')
MK Rana
fuente
1
¡Esto no es útil!
Tripulse