Транспонирование матрицы в Python

144

Я пытаюсь создать функцию транспонирования матрицы для python, но, похоже, мне не удается заставить ее работать. Скажи, что у меня есть

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

и я хочу, чтобы моя функция придумала

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

Другими словами, если бы я распечатал этот 2D-массив в виде столбцов и строк, я бы хотел, чтобы строки превратились в столбцы, а столбцы в строки.

Я сделал это до сих пор, но это не работает

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
Хулио Диас
источник

Ответы:

314

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
источник
15
если вы собираетесь перебирать результаты, izipfrom itertoolsможет сэкономить память для больших массивов.
Энтони Хэтчкинс
Как бы вы могли вернуть список для подсписок? Вроде [['a', 'b', 'g'], ['d', 'e', 'h'], ['c', 'f', 'i']]вместо [('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]?
acollection_
15
@acollection_: map(list, zip(*theArray)).
jfs
1
@AntonyHatchkins Это не требуется для Python 3.0 и выше. Там zipуже возвращает итератор: docs.python.org/3.0/whatsnew/…
xuiqzy
1
@xuiqzy Не то чтобы я об этом не знал, но это правда.
Энтони Хэтчкинс,
65
>>> 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']]

генератор списков создает новый двумерный массив с элементами списка вместо кортежей.

sqwerl
источник
Это правильный путь, если вы хотите присвоить результат переменной (в отличие, например, от прямого перебора) - при условии, что вам нужны списки, а не кортежи, как уже упоминалось.
ASL
Другой вариант (как следует из комментариев в принятом ответе):list(map(list, zip(*theArray)))
ASL
38

Если ваши строки не равны, вы также можете использовать map:

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

Изменить: в Python 3 функциональность mapизменена, itertools.zip_longestвместо этого можно использовать:
Источник: Что нового в 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
источник
16

Намного проще с 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')
Иршад Бхат
источник
7

Проблема с исходным кодом заключалась в том, что вы инициализировали transpose[t]каждый элемент, а не только один раз для каждой строки:

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

Это работает, хотя есть и другие способы Pythonic для выполнения тех же zipзадач , включая приложение @JF .

Нед Батчелдер
источник
1
Обратите внимание, что эта реализация не работает с матрицами, которые имеют разное количество столбцов и строк
Вектор
5

Чтобы завершить ответ Дж. Ф. Себастьяна, если у вас есть список списков разной длины, ознакомьтесь с этим отличным постом от ActiveState . Короче говоря:

Встроенная функция zip выполняет аналогичную работу, но обрезает результат до длины самого короткого списка, поэтому некоторые элементы из исходных данных могут быть впоследствии потеряны.

Для обработки списка списков разной длины используйте:

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)
Франк Дернонкур
источник
Это хороший улов. Однако в матрицах нет списков разной длины.
Olli
Это зависит от того, как они хранятся.
Franck Dernoncourt 09
4

«Лучший» ответ уже отправлен, но я подумал, что добавлю, что вы можете использовать вложенные списки, как показано в учебнике Python .

Вот как можно получить транспонированный массив:

def matrixTranspose( matrix ):
    if not matrix: return []
    return [ [ row[ i ] for row in matrix ] for i in range( len( matrix[ 0 ] ) ) ]
leetNightshade
источник
2

Это сохранит прямоугольную форму, так что последующие транспозиции дадут правильный результат:

import itertools
def transpose(list_of_lists):
  return list(itertools.izip_longest(*list_of_lists,fillvalue=' '))
Вануан
источник
2

вы можете попробовать это с пониманием списка, как показано ниже

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
источник
0

Если вы хотите транспонировать матрицу типа A = np.array ([[1,2], [3,4]]), вы можете просто использовать AT, но для вектора, такого как a = [1,2], aT не возвращает транспонирование! и вам нужно использовать a.reshape (-1, 1), как показано ниже

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

Вы можете сделать это, просто используя понимание 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]))]
Расул Бедделан
источник
Хотя это может быть правильный ответ. Две строчки кода не очень полезны без объяснения того, что и как они решают исходный вопрос. Опишите подробно свой ответ.
RyanNerd
1
при размещении нового ответа на старый вопрос ожидания высоки. Пожалуйста, не
Жан-Франсуа Фабр
-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'
roo.firebolt
источник
-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
Равнит Сингх
источник
Это простая реализация для транспонирования, хотя также доступны библиотеки, подобные упомянутым в других ответах.
Равнит Сингх,
-4

`

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

`Эта функция вернет транспонированный

user2412711
источник
-4

Программа Python для транспонирования матрицы:

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
Это бесполезно!
tripulse