There is a numpy
helper function for this, np.apply_along_axis
:
>>> import numpy as np
>>> D = np.hstack((np.ones(5).reshape(-1,1),2*np.ones(5).reshape(-1,1)))
>>> np.apply_along_axis(lambda x: x[0] + x[1], 1, D)
array([3., 3., 3., 3., 3.])
Although you may have to re-shape the results:
>>> np.apply_along_axis(lambda x: x[0] + x[1], 1, D)[...,None]
array([[3.],
[3.],
[3.],
[3.],
[3.]])
In any case, this will not be very efficient, it will be significantly slower than using numpy
vectorized operations, and so you should do something like this:
>>> D[..., [0]] + D[..., [1]]
array([[3.],
[3.],
[3.],
[3.],
[3.]])
If at all possible. Although, I wonder if this might be more efficient actually:
>>> (D[..., 0] + D[..., 1])[...,None]
array([[3.],
[3.],
[3.],
[3.],
[3.]])
EDIT:
Yea, the latter is definitely faster:
>>> arr = D.repeat(100_000, 0)
>>> from timeit import timeit
>>> timeit("arr[..., [0]] + arr[..., [1]]", setup="from __main__ import arr, np ", number=1000)
1.7564522250000323
>>> timeit("(arr[..., 0] + arr[..., 1])[..., None]", setup="from __main__ import arr, np ", number=1000)
0.5029663629999845
And of course, either of these are much faster than apply_along_axis
:
>>> timeit("np.apply_along_axis(lambda x: x[0] + x[1], 1, arr)", setup="from __main__ import arr, np ", number=10)
8.547392725000009
Note, the above was repeated ten times versus the pure numpy versions which I repeated one thousand times, and it still took ten times longer, which is 3 orders of magnitude faster (pretty typical for numpy vs python). Heck, I think just dropping into Python might be faster, so using a list comprehension:
>>> timeit("np.array([x[0] + x[1] for x in arr])", setup="from __main__ import arr, np ", number=10)
2.1825029110000287
Again, note that the above is repeated only 10 times. If I do the original timings only 10 times, just to show the stark contrast directly:
>>> timeit("arr[..., [0]] + arr[..., [1]]", setup="from __main__ import arr, np ", number=10)
0.023796129999936966
>>> timeit("(arr[..., 0] + arr[..., 1])[..., None]", setup="from __main__ import arr, np ", number=10)
0.007688513000061903
So stick to (arr[..., 0] + arr[..., 1])[..., None]
if you want to go many hundreds to a thousand times faster.