I would like to speed up this short piece of code
max_x=array([max(x[(id==dummy)]) for dummy in ids])
x and id are numpy arrays of the same dimensions and ids is an array of smaller dimension.
What is the fast way to do it using vectorial operation?
This is not easy to do vectorize further (as far as I see), unless id has some structure. Otherwise a bottleneck might be doing
id==dummyoften, but the only solution I can think of would be the use of sorting, and due to the lack of a reduce functionality for np.max() still requires quite a bit of python code (Edit: There actually is a reduce function through np.fmax available). This is about 3x faster for a x being 1000×1000 and id/ids being in 0..100, but as its rather complex, its only worth it for larger problems with many ids:I originally offered this solution which does a pure python loop over the slices, but below is a shorter (and faster) version:
EDIT: improved version for calculation of the maxium for each slice:
There is a way to remove the python loop by the use of
np.fmax.reduceat, which might outperform the previous one a lot if the slices are small (and is actually quite elgant):Now there are probably some small things where it is possible to make this a little faster.
If id/ids has some structure it should be possible to simplify the code, and maybe use a different approach to achieve a much larger speedup. Otherwise the speedup of this code should be large, as long as there are many (unique) ids (and x/id arrays are not very small).
Note that the code enforces np.unique(ids), which is probably a good assumption though.