I had like to know the best 开发者_JS百科fatest/optimized way of getting the maximum values element-wised of "n" matrices in Python/Numpy.
For example:
import numpy as np
matrices=[np.random.random((5,5)) for i in range(10)]
# the function np.maximum from numpy only works for two matrices.
max_matrix=np.maximum(matrices[0],matrices[1])
max_matrix=np.maximum(*matrices) # <- error
How would you overcome this problem?
Use reduce
:
reduce(np.maximum, matrices)
From the docs:
reduce
(function, iterable[, initializer])Apply function of two arguments cumulatively to the items of iterable, from left to right, so as to reduce the iterable to a single value. For example,
reduce(lambda x, y: x+y, [1, 2, 3, 4, 5])
calculates((((1+2)+3)+4)+5)
. The left argument,x
, is the accumulated value and the right argument,y
, is the update value from the iterable. If the optional initializer is present, it is placed before the items of the iterable in the calculation, and serves as a default when the iterable is empty. If initializer is not given and iterable contains only one item, the first item is returned.
import numpy as np
matrices=[np.random.random((5,5)) for i in range(10)]
np.max(np.hstack(matrices))
Will give you the maximum value from all of the n matrices. This basically merges all of the matrices in matrices
into a single array using np.hstack
and then takes the max of that new array. This assumes that all of your matrices have the same number of rows. You can also use np.vstack
or np.concatenate
to achieve a similar effect.
Edit I re-read your question and you might actually want something more like:
np.max(np.dstack(matrices),axis=2)
This will stack all of your matrices along a third axis and then give you the max along that direction, returning a 5x5 matrix for your case.
Edit #2 Here are some timings:
In [33]: matrices = [np.random.random((5,5)) for i in range(10)]
In [34]: %timeit np.dstack(matrices).max(2)
10000 loops, best of 3: 92.6 us per loop
In [35]: %timeit np.array(matrices).max(axis=0)
10000 loops, best of 3: 90.9 us per loop
In [36]: %timeit reduce(np.maximum, matrices)
10000 loops, best of 3: 25.8 us per loop
and for some larger arrays:
In [37]: matrices = [np.random.random((200,200)) for i in range(100)]
In [38]: %timeit np.dstack(matrices).max(2)
10 loops, best of 3: 111 ms per loop
In [39]: %timeit np.array(matrices).max(axis=0)
1 loops, best of 3: 697 ms per loop
In [40]: %timeit reduce(np.maximum, matrices)
100 loops, best of 3: 12.7 ms per loop
Steven wins!
精彩评论