Issue
I am hoping to achieve the following and return 'result'.
Is there a way to make the following code more efficient? Thank you in advance.
The problem for me is that x.shape[1]
would not just be 2 anymore in my real problem. It can be 100 or even more. Hence accessing idx
would be much more difficult. I am not sure how I should improve this.
import numpy as np
np.random.seed(0)
x = np.random.randint(0, high = 50, size = (5, 2))
y = np.random.randint(0, high = 50, size = (5))
result = np.zeros(5)
for i in range(len(x)):
idx =( x[:,0]<= x[i,0]) & (x[:,1]<= x[i,1])
#print(y[idx])
result[i] = np.sum(y[idx])
Solution
Use broadcasting:
# compare x to itself and aggregate with all
idx = (x <= x[:, None]).all(axis=2)
# broadcast y using the boolean mask
# to have the value if True and 0 if False
# then sum
result = (y * idx).sum(axis=0)
Output: array([23, 30, 48, 72, 24])
Used input (with np.random.seed(0)
):
# x
array([[44, 47],
[ 0, 3],
[ 3, 39],
[ 9, 19],
[21, 36]])
# y
array([23, 6, 24, 24, 12])
Intermediates:
# idx
array([[ True, True, True, True, True],
[False, True, False, False, False],
[False, True, True, False, False],
[False, True, False, True, False],
[False, True, False, True, True]])
# y * idx
array([[23, 6, 24, 24, 12],
[ 0, 6, 0, 0, 0],
[ 0, 6, 24, 0, 0],
[ 0, 6, 0, 24, 0],
[ 0, 6, 0, 24, 12]])
operations other than sum
If you want to compute something other than a sum you might be annoyed by the 0s and would prefer NaNs.
In this case better use where
:
np.where(idx, y, np.nan)
# array([[23., 6., 24., 24., 12.],
# [nan, 6., nan, nan, nan],
# [nan, 6., 24., nan, nan],
# [nan, 6., nan, 24., nan],
# [nan, 6., nan, 24., 12.]])
np.nansum(np.where(idx, y, np.nan), axis=0)
# array([23., 30., 48., 72., 24.])
optimization of the loop approach
While broadcasting is better, you could also have improved the slicing part in your loop to act on all columns at once:
for i in range(len(x)):
idx = (x<=x[i]).all(1)
result[i] = np.sum(y[idx])
Answered By - mozway
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.