web-dev-qa-db-ja.com

Pythonの行列の転置

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

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')]
291
jfs
>>> 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配列を作成します。

62
sqwerl

行が等しくない場合は、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を使用できます。
出典: What's New In Python 3.

>>> 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')]
34
bigjim

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')
15
Irshad Bhat

J.F. 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)
4

元のコードの問題は、行ごとに1回ではなく、すべての要素で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

これは機能しますが、@ J.F。のZipアプリケーションを含め、同じことを達成するためのPython的な方法が他にもあります。

4
Ned Batchelder

「最良の」答えはすでに提出されていますが、 Python Tutorial に見られるように、ネストされたリストの内包表記を使用できると付け加えたいと思いました。

転置配列を取得する方法は次のとおりです。

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

これは長方形の形状を保持するため、後続の転置で正しい結果が得られます。

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

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
Hassan Bahaloo