-1

I have two lists that have the same amount of elements. Each element is a number (float). I need to find the 10 greatest values in the first list, then find those values in the second list that have the same indices as the indices of the 10 greatest values in the first list. How can I do that? (I want to use numpy if possible). For instance:

a= [0.5, 2.9, 9.7]
b= [1, 3, 5.8]

I need the 2 greatest values from list a, which are 2.9 and 9.7. Their indices are 1 and 2, and so I need 3 and 5.8 from list b.

I haven't tried anything yet, I thought about amax or something, but I don't know.

Vikih
  • 9
  • 2
  • 1
    Please provide a meaningful reproducible example (input+output) for clarity – mozway May 17 '23 at 09:32
  • 1
    @Vikih people who post questions are expected to perform enough research and efforts. You should try to come up with a solution yourself before posting a question. – Programmer-RZ May 17 '23 at 09:41
  • numpy is not the panacea for all ills. Don't use it just for the sake of it. This requirement is trivial and can very easily be implemented in Python without the need for additional modules – DarkKnight May 17 '23 at 09:46
  • @DarkKnight if you already have numpy arrays and potentially large data, this is straightforward and efficient in numpy, why wouldn't you use it? – mozway May 17 '23 at 09:50
  • @mozway Agreed but there's nothing in this question that alludes to the pre-existence of numpy arrays. OP thinks that numpy *may* provide the solution and she may be right. What I'm saying is that it's unnecessary - but that's just my opinion which obviously doesn't count for much – DarkKnight May 17 '23 at 10:06

2 Answers2

0

Assuming this example (integers here for clarity, but this works identically with floats)

a1 = np.array([11,  6, 13,  8,  9,  5,  7, 10,  3, 14, 12,  4,  2,  1,  0])
# top 10:       x   x   x   x   x   x   x   x       x   x
a2 = np.array([ 0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14])

You can find the indices of the top 10 values with numpy.argpartition, then index your second array:

out = a2[np.argpartition(a1, -10)[-10:]]
# array([ 5,  1,  6,  3,  4,  7, 10,  9,  2,  0])

If you want them in order:

out = a2[np.sort(np.argpartition(a1, -10)[-10:])]
# array([ 0,  1,  2,  3,  4,  5,  6,  7,  9, 10])

updated example:

a = np.array([0.5, 2.9, 9.7])
b = np.array([1, 3, 5.8])

out = b[np.sort(np.argpartition(a, -2)[-2:])]
# array([3. , 5.8])

pure python approach

a = [0.5, 2.9, 9.7]
b = [1, 3, 5.8]

N = 2
Nth = sorted(a)[-N]
out = [val_b for val_a, val_b in zip(a, b) if val_a >= Nth]
# [3, 5.8]
mozway
  • 194,879
  • 13
  • 39
  • 75
  • Anything unclear/incorrect in my answer? – mozway May 17 '23 at 09:39
  • @DarkKnight yes it is (I agree my example is not the best), but check the `x` marks in my answer, you see the `8` and `11` to `14` values are missing as expected. Try with `a2 = np.array(['A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 'O'])` – mozway May 17 '23 at 10:04
0

My interpretation of the requirement may not be correct. However, without additional modules I would do this:

a = [11, 6, 13, 8, 9, 5, 7, 10, 3, 14, 12, 4, 2, 1, 0]
b = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14]

a1 = [0.5, 2.9, 9.7]
b1 = [1, 3, 5.8]

def process(a, b, t):
    s = sorted([(v, i) for i, v in enumerate(a)])
    return [b[i] for _, i in s[-t:]]

print(process(a, b, 10))
print(process(a1, b1, 2))

Output:

[5, 1, 6, 3, 4, 7, 0, 10, 2, 9]
[3, 5.8]

Explanation:

Build a list of 2-tuples (value, index). Natural sort will be based on the values (first part of the tuple). Build output list using the indexes from the previously sorted list.

The output here differs from the answer provided using numpy but that doesn't seem to be a functional issue more of an understanding of the requirement

DarkKnight
  • 19,739
  • 3
  • 6
  • 22