2013-12-11 70 views
2

比方說,我有一個2D NumPy的ndarray,就像這樣:如何有效地將矩陣變換應用於NumPy數組的每一行?

[[ 0, 1, 2, 3 ], 
[ 4, 5, 6, 7 ], 
[ 8, 9, 10, 11 ]] 

從概念上來講,我想要做的是這樣的:

For each row: 
    Transpose the row 
    Multiply the transposed row by a transformation matrix 
    Transpose the result 
    Store the result in the original ndarray, overwriting the original row data 

我有一個極其緩慢,蠻力方法在功能上實現這一點:

import numpy as np 
transform_matrix = np.matrix(/* 4x4 matrix setup clipped for brevity */) 
for i, row in enumerate(data): 
    tr = row.reshape((4, 1)) 
    new_row = np.dot(transform_matrix, tr) 
    data[i] = new_row.reshape((1, 4)) 

但是,這似乎是NumPy應該做的那種操作w第i個。我假設 - 作爲NumPy的新手 - 我只是在文檔中缺少一些基本的東西。任何指針?

請注意,如果創建新的ndarray比創建新的ndarray更快,而不是就地編輯它,那也適用於我正在做的事情;主要關心的是手術的速度。

回答

8

漫長的系列要執行的操作等同於以下內容:

data[:] = data.dot(transform_matrix.T) 

或使用新的陣列,而不是修改原始,這應該是快了一點:

data.dot(transform_matrix.T) 

下面是解釋:

For each row: 
    Transpose the row 

等價於轉置矩陣ix然後通過專欄。

Multiply the transposed row by a transformation matrix 

將矩陣的每列左乘第二個矩陣相當於將整個矩陣左乘以第二矩陣。在這一點上,你有什麼是transform_matrix.dot(data.T)

Transpose the result 

一個矩陣的轉置是transform_matrix.dot(data.T).T相當於data.dot(transform_matrix.T)的基本屬性。

Store the result in the original ndarray, overwriting the original row data 

切片分配完成此操作。

+0

切片是多餘這裏,我想 – alko

+1

完善!感謝您也通讀了解釋 - 這非常有幫助。 – user3089880

2

看來你需要transpose operator

>>> np.random.seed(11) 
>>> transform_matrix = np.random.randint(1, 10, (4,4)) 
>>> np.dot(transform_matrix, data.T).T 
matrix([[ 24, 24, 17, 37], 
     [ 76, 108, 61, 137], 
     [128, 192, 105, 237]]) 

或等價地,爲(A * B).T =(BT * AT):

>>> np.dot(data, transform_matrix.T) 
+0

+1指向矩陣代數 - 這不是一個編程問題,但缺乏對矩陣代數的理解 – DCS

相關問題