Python中的矩阵转置


142

我正在尝试为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

Answers:


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
如果您要遍历结果,则izipfrom itertools可以为大型数组节省内存。
Antony Hatchkins 2013年

您将如何返回子列表的列表?喜欢[['a', 'b', 'g'], ['d', 'e', 'h'], ['c', 'f', 'i']]而不是[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]
acollection_

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

1
@AntonyHatchkins Python 3.0及更高版本不需要此功能。在那里,zip:已经返回迭代docs.python.org/3.0/whatsnew/...
xuiqzy

1
@xuiqzy不是我不知道,但这是事实。
安东尼·哈奇金斯

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

列表生成器使用列表项而不是元组创建一个新的2d数组。


如果您想将结果分配给变量(而不是例如直接对其进行迭代),则可以采用这种方法-假设您想要的是列表而不是元组,如上所述。
ASL

另一个选择(如接受的答案中的评论所暗示)是:list(map(list, zip(*theArray)))
ASL

37

如果行数不相等,也可以使用map

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

编辑:在Python 3中mapitertools.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')]

15

使用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

原始代码的问题在于,您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

尽管有更多的Python方式可以完成相同的工作,包括@JF的zip应用程序,但这种方法仍然有效。


1
请注意,此实现不适用于具有不同列和行数的矩阵
Vector

4

要完成JF Sebastian的答案,如果您有长度不一的列表,请查看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 2012年

这取决于它们的存储方式。
Franck Dernoncourt 2013年

3

“最佳”答案已经提交,但是我想我要补充一下,您可以使用嵌套列表推导,如Python教程中所示

这是获取转置数组的方法:

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

1

这将保留矩形形状,以便随后的转置将获得正确的结果:

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

1

您可以像下面这样使用列表理解来尝试

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

它是转置的简单实现,尽管也有其他答案中提到的库。
Ravneet Singh

-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,
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.