Matrix中的矩阵转置

Jul*_*iaz 134 python list multidimensional-array

我正在尝试为python创建一个矩阵转置函数,但我似乎无法使它工作.说我有

theArray = [['a','b','c'],['d','e','f'],['g','h','i']]
Run Code Online (Sandbox Code Playgroud)

我希望我的功能能够提出来

newArray = [['a','d','g'],['b','e','h'],['c', 'f', 'i']]
Run Code Online (Sandbox Code Playgroud)

换句话说,如果我要将这个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
Run Code Online (Sandbox Code Playgroud)

jfs*_*jfs 297

Python 2:

>>> theArray = [['a','b','c'],['d','e','f'],['g','h','i']]
>>> zip(*theArray)
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]
Run Code Online (Sandbox Code Playgroud)

Python 3:

>>> [*zip(*theArray)]
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]
Run Code Online (Sandbox Code Playgroud)

  • 如果你要遍历结果,来自`itertools`的`izip`可以为大型数组节省内存. (14认同)
  • @acollection_:`map(list,zip(*theArray))`. (12认同)

sqw*_*erl 62

>>> 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']]
Run Code Online (Sandbox Code Playgroud)

列表生成器创建一个新的2d数组,其中包含列表项而不是元组.


big*_*jim 35

如果您的行不相等,您还可以使用map:

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

编辑:在Python 3中map,itertools.zip_longest可以使用改变的功能:
Source: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')]
Run Code Online (Sandbox Code Playgroud)


Irs*_*hat 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')
Run Code Online (Sandbox Code Playgroud)


Ned*_*der 8

原始代码的问题在于您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
Run Code Online (Sandbox Code Playgroud)

这有效,尽管有更多 Pythonic 方法可以完成相同的事情,包括 @JF 的zip应用程序。


Fra*_*urt 5

要完成 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)
Run Code Online (Sandbox Code Playgroud)


lee*_*ade 5

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

以下是获得转置数组的方法:

def matrixTranspose( matrix ):
    if not matrix: return []
    return [ [ row[ i ] for row in matrix ] for i in range( len( matrix[ 0 ] ) ) ]
Run Code Online (Sandbox Code Playgroud)