0

I have a list of positive integers and I want to repeatedly subtract the smallest element from all elements, but only if the element isn't an instance of the minimum. For example, in one iteration

a = np.array([3, 5, 9, 3, 3]) becomes [3, 2, 6, 3, 3] and ultimately [1,1,1,1,1].

That is, no entry is ever reduced to 0. I'm suspicious there may exist an easy way to modify a - min(a) such that a[0], a[3], and a[4] don't become 0, but I don't know.

I know this can be accomplished with a list comprehension:

while len(set(arr)) > 1:

arr = [a - min(arr) if a > min(arr) else a for a in arr]

The arrays may be very large though, so with time efficiency in mind I'm hoping NumPy has a convenient way of doing this. I'm quite new to Python, so correction/information in all capacities is appreciated.

1
  • 2
    I believe the end result will be an array full of the GCD of the original array. Commented Oct 24, 2019 at 14:45

1 Answer 1

1

This can be handled using the 3-clause variant of the where function:

>>> import numpy as np
>>> a = np.array([3, 5, 9, 3, 3])
>>> m = a.min()
>>> np.where(a != m, a - m, m)
array([3, 2, 6, 3, 3])

And wrap that in the while loop.

Instead of using set, you could also use numpy.unique:

while len(np.unique(a)) > 1:
    m = a.min()
    a = np.where(a != m, a - m, m)

But you should time both variations (set versus unique, list comprehension versus where) separately to see what works fastest for larger arrays.

Another variant is to compare the maximum and minimum: perhaps a.max() can be calculated faster than np.unique:

while True:
    m = a.min()
    if m == a.max():
        break
    a = np.where(a != m, a - m, m)
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.