hrschbck
hrschbck

Reputation: 117

NumPy replace values with arrays based on conditions

I am trying to produce a sorter that, for each weekly total (for multiple different products), places them in the right buckets based on the max cumulative allowable less what has already been sorted.

maxes=np.array([100,200,300],[100,400,900])
weeklytotals=np.array([100,150,200,250],[200,400,600,800)]

The desired output would be:

result=np.array([[100,0,0],[100,50,0],[100,100,0],[100,150,0]],[[100,100,0],[100,300,0],[100,400,100],[100,400,300]]

I do not want to use loops but I am racking my mind on how to avoid that method. Thanks in advance, still a Python beginner. I want to use NumPy because the end implementation will need to be extremely fast.

Upvotes: 0

Views: 70

Answers (1)

akuiper
akuiper

Reputation: 214957

One vectorized approach could be:

result = np.minimum(weeklytotals[:,:,None], maxes.cumsum(1)[:,None,:])
result[...,1:] -= result[...,:-1]
result

#array([[[100,   0,   0],
#        [100,  50,   0],
#        [100, 100,   0],
#        [100, 150,   0]],

#       [[100, 100,   0],
#        [100, 300,   0],
#        [100, 400, 100],
#        [100, 400, 300]]])

Firstly calculate the cumulative capacity for the buckets:

maxes.cumsum(1)
#array([[ 100,  300,  600],
#       [ 100,  500, 1400]])

calculate the cumulative amount in the buckets by taking the minimum between weekly total and capacity:

result = np.minimum(weeklytotals[:,:,None], maxes.cumsum(1)[:,None,:])

#array([[[100, 100, 100],
#        [100, 150, 150],
#        [100, 200, 200],
#        [100, 250, 250]],

#       [[100, 200, 200],
#        [100, 400, 400],
#        [100, 500, 600],
#        [100, 500, 800]]])

Take the difference of amounts between buckets and assign them back (except for the first bucket):

result[...,1:] -= result[...,:-1]
result

Upvotes: 3

Related Questions