Транспонирование матрицы в 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')]

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

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


Это правильный путь, если вы хотите присвоить результат переменной (в отличие, например, от прямого перебора) - при условии, что вам нужны списки, а не кортежи, как уже упоминалось.
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')]

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

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)


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'

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

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


-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
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.