I have an array in which I want to find the index of the smallest elements. I have tried the following method:
distance = [2,3,2,5,4,7,6]
a = distance.index(min(distance))
This returns 0, which is the index of the first smallest distance. However, I want to find all such instances, 0 and 2. How can I do this in Python?
Use np.where to get all the indexes that match a given value:
import numpy as np
distance = np.array([2,3,2,5,4,7,6])
np.where(distance == np.min(distance))[0]
Out[1]: array([0, 2])
Numpy outperforms other methods as the size of the array grows:
Length of Array x 7
Method 1 10 20 50 100 1000
Sorted Enumerate 2.47 16.291 33.643
List Comprehension 1.058 4.745 8.843 24.792
Numpy 5.212 5.562 5.931 6.22 6.441 6.055
Defaultdict 2.376 9.061 16.116 39.299
You may enumerate array elements and extract their indexes if the condition holds:
min_value = min(distance)
[i for i,n in enumerate(distance) if n==min_value]
#[0,2]
Surprisingly the numpy
answer seems to be the slowest.
Update: Depends on the size of the input list.
import numpy as np
import timeit
from collections import defaultdict
def weird_function_so_bad_to_read(distance):
se = sorted(enumerate(distance), key=lambda x: x[1])
smallest_numb = se[0][1] # careful exceptions when list is empty
return [x for x in se if smallest_numb == x[1]]
# t1 = 1.8322973089525476
def pythonic_way(distance):
min_value = min(distance)
return [i for i, n in enumerate(distance) if n == min_value]
# t2 = 0.8458914929069579
def fastest_dont_even_have_to_measure(np_distance):
# np_distance = np.array([2, 3, 2, 5, 4, 7, 6])
min_v = np.min(np_distance)
return np.where(np_distance == min_v)[0]
# t3 = 4.247801031917334
def dd_answer_was_my_first_guess_too(distance):
d = defaultdict(list) # a dictionary where every value is a list by default
for idx, num in enumerate(distance):
d[num].append(idx) # for each number append the value of the index
return d.get(min(distance))
# t4 = 1.8876687170704827
def wrapper(func, *args, **kwargs):
def wrapped():
return func(*args, **kwargs)
return wrapped
distance = [2, 3, 2, 5, 4, 7, 6]
t1 = wrapper(weird_function_so_bad_to_read, distance)
t2 = wrapper(pythonic_way, distance)
t3 = wrapper(fastest_dont_even_have_to_measure, np.array(distance))
t4 = wrapper(dd_answer_was_my_first_guess_too, distance)
print(timeit.timeit(t1))
print(timeit.timeit(t2))
print(timeit.timeit(t3))
print(timeit.timeit(t4))
You can also do the following list comprehension
distance = [2,3,2,5,4,7,6]
min_distance = min(distance)
[index for index, val in enumerate(distance) if val == min_distance]
>>> [0, 2]
We can use an interim dict to store indices of the list and then just fetch the minimum value of distance from it. We will also use a simple for-loop here so that you can understand what is happening step by step.
from collections import defaultdict
d = defaultdict(list) # a dictionary where every value is a list by default
for idx, num in enumerate(distance):
d[num].append(idx) # for each number append the value of the index
d.get(min(distance)) # fetch the indices of the min number from our dict
[0, 2]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.