Let's say I have a 2d NumPy ndarray, like so:
[[ 0, 1, 2, 3 ],
[ 4, 5, 6, 7 ],
[ 8, 9, 10, 11 ]]
Conceptually speaking, what I want to do is this:
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
I have an extremely slow, brute-force method which functionally achieves this:
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 ) )
However, this seems like the sort of operation that NumPy should do well with. I assume that - as someone new to NumPy - I'm just missing something fundamental in the documentation. Any pointers?
Note that if it's faster to create a new ndarray rather than edit it in-place, that can work for what I'm doing, too; speed of the operation is the primary concern.
We can use numpy. flatten() function to convert the matrix to an array. It takes all N elements of the matrix placed into a single dimension array.
The key to making it fast is to use vectorized operations, generally implemented through NumPy's universal functions (ufuncs). This section motivates the need for NumPy's ufuncs, which can be used to make repeated calculations on array elements much more efficient.
The lengthy series of operations you want to perform is equivalent to the following:
data[:] = data.dot(transform_matrix.T)
or using a new array instead of modifying the original, which should be a bit faster:
data.dot(transform_matrix.T)
Here's the explanation:
For each row:
Transpose the row
Equivalent to transposing the matrix and then going over the columns.
Multiply the transposed row by a transformation matrix
Left-multiplying each column of a matrix by a second matrix is equivalent to left-multiplying the whole thing by the second matrix. At this point, what you have is transform_matrix.dot(data.T)
Transpose the result
One of the basic properties of matrix transposes is that transform_matrix.dot(data.T).T
is equivalent to data.dot(transform_matrix.T)
.
Store the result in the original ndarray, overwriting the original row data
The slice assignment does this.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With