Python 二維矩陣 行列轉置的幾種實現方法
阿新 • • 發佈:2020-09-19
最近在讀寫 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(*) 函式就可以快速實現二維矩陣轉置了,當然使用其他一些專用的庫也是可以的,在效能和便捷程度上做好取捨就可以了,希望對需要的朋友有幫助,感謝支援~