2013-12-11 5 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 следует делать хорошо Ith. Я предполагаю, что - как кто-то новый для NumPy - я просто пропустил что-то фундаментальное в документации. Любые указатели?

Обратите внимание, что если быстрее создать новый ndarray, а не редактировать его на месте, это может работать и для того, что я делаю; скорость операции является основной задачей.

ответ

8

Длительная серия операций, которые вы хотите выполнить это эквивалентно следующему:

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

или использовать новый массив вместо изменения оригинала, который должен быть немного быстрее:

data.dot(transform_matrix.T) 

Вот объяснение:

For each row: 
    Transpose the row 

Эквивалент транспозиции Matr 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

Смежные вопросы