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(*) 函數就可以快速實現二維矩陣轉置了,當然使用其他一些專用的庫也是可以的,在性能和便捷程度上做好取舍就可以了,希望對需要的朋友有幫助,感謝支持~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM