1. 程式人生 > 實用技巧 >Python 二維矩陣 行列轉置的幾種實現方法

Python 二維矩陣 行列轉置的幾種實現方法

最近在讀寫 MySQL 資料的過程中,碰到了需要處理 二維矩陣資料 行列轉置 的問題,比如將:

[[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
# 注意:矩陣中每個子序列的長度是相同的

轉化成:

[[1, 5, 9],
 [2, 6, 10],
 [3, 7, 11],
 [4, 8, 12]]
# 行列轉置之後的結果

在研究了一番之後,總結了以下這些方法,做個記錄。

1. 最基礎的 for 迴圈

def transpose_2d(data):
    transposed = []
    for i in range(len(data[0])):
        new_row = []
        for row in data:
            new_row.append(row[i])
        transposed.append(new_row)
    return transposed


data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
print(transpose_2d(data))

# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
# [Finished in 0.1s]

2. 使用列表推導式 List Comprehension

這個其實是第一種方法的高階簡化寫法。

def transpose_2d(data):
    transposed = [[row[i] for row in data] for i in range(len(data[0]))]
    return transposed


data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
print(transpose_2d(data))

# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
# [Finished in 0.1s]

3. 使用 zip(*iterable) 函式(推薦)

一種高效的寫法,因為 list, map, zip 都是 Python 內建的函式 (Built-ins)。

def transpose_2d(data):
    # transposed = list(zip(*data))
    # [(1, 5, 9), (2, 6, 10), (3, 7, 11), (4, 8, 12)]
    # 注意 zip 本身返回的資料型別為 tuple 元組
    # 其中符號 * 號可以對元素進行解壓或展開

    transposed = list(map(list, zip(*data)))
    return transposed


data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]
print(transpose_2d(data))

# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
# [Finished in 0.1s]

4. 使用 numpy 的 T 轉置

from numpy import transpose

data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

transposed = transpose(data).tolist()
print(transposed)

# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
# [Finished in 0.3s]
# 速度中規中矩,畢竟 numpy 用來處理數學更好

5. 使用 pandas 的 T 轉置

from pandas import DataFrame

data = [[1, 2, 3, 4], [5, 6, 7, 8], [9, 10, 11, 12]]

transposed = DataFrame(data).T.values.tolist()
print(transposed)

# [[1, 5, 9], [2, 6, 10], [3, 7, 11], [4, 8, 12]]
# [Finished in 0.7s]
# 可能因為 pandas 本身呼叫了其他的庫,這裡明顯感覺偏慢,殺雞用牛刀了

總結

綜上,在一般情況下,我們直接使用 Python 內建的 zip(*) 函式就可以快速實現二維矩陣轉置了,當然使用其他一些專用的庫也是可以的,在效能和便捷程度上做好取捨就可以了,希望對需要的朋友有幫助,感謝支援~