Let's say we have two sorted numpy arrays, a and b.

a = np.array([ 0,  1,  2, 10])
b = np.array([ 7, 13])

For each element array a, I want to subtract the first larger element in b to get something like this:

>>> f(a, b)
array([-7, -6, -5, -3])

I can do this with an inefficient for loop, but is there a more numpythonic way to do it?

3 Answers

Mark Meyer On

You could use searchsorted for this. It will require that b is sorted and that a doesn't have values greater than the largest in b.

> a = np.array([0, 1, 2, 10, 12, 5, 7])
> b = np.array([7, 13])
> a - b[np.searchsorted(b, a, side='right')]

array([-7, -6, -5, -3, -1, -2, -6])
Alain T. On

The title and explanations are inconsistent.

Assuming that you're looking for the first element of b that is larger, not the smallest of b that is larger, then this will do it:

a - b[np.argmax(a[:,None]<b,axis=1)]

# array([-7, -6, -5, -3])

If you do need the smallest that is larger, you could sort b beforehand using b = np.sort(b) but then, using searchsorted(), as proposed by Mark Meyer, will be more efficient.

note that you must have at least one element in b that is larger than the largest element of a

Community On

You should try this solution even if it is not an built in function because it is much more flexible. (works in all situations):

def subtract(a, b):
    final = []
    if b.__len__() != 0 and a.__len__() != 0:
        biggest = b[0]
        for j in range(b.__len__()):
            if b[j] < biggest:
                biggest = b[j]
        for i in range(a.__len__()):
            if a[i] > biggest:
                final.insert(final.__len__(), biggest-a[i])
                final.insert(final.__len__(), a[i]-biggest)
    return final