[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



답변

파이썬 2 :

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

파이썬 3 :

>>> [*zip(*theArray)]
[('a', 'd', 'g'), ('b', 'e', 'h'), ('c', 'f', 'i')]


답변

>>> 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 배열을 만듭니다.


답변

행이 같지 않으면 다음을 사용할 수도 있습니다 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')]


답변

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


답변

원래 코드의 문제점은 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

@JF의 zip응용 프로그램을 포함하여 동일한 일을 수행하는 더 많은 Pythonic 방법이 있지만 작동 합니다.


답변

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)


답변

“최고의”답변이 이미 제출되었지만 Python Tutorial 에서 볼 수 있듯이 중첩 목록 이해를 사용할 수 있다고 덧붙였습니다 .

다음은 조옮김 배열을 얻는 방법입니다.

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