Counting number of elements less than and adding it to the original in Python

Question:

I have two lists I1 and I2. I am comparing elements of I2 to elements in I1 and want to add the number of elements which are less than or equal to it. For example, 11 in I2 has two two elements less than or equal to it in I1. Hence, 2 should be added to 11. Similarly, for elements 27 and 41 in I2. I present the current and expected output.

I1=[1,11,13,16,26,30,43,46]

I2=[11,27,41]
I2=[i for i in I2 if I2<=I1]
print("I2 =",I2)

The current output is

I2 = []

The expected output is

I2 = [13,32,47]
Asked By: user20032724

||

Answers:

Try this.

lst1 = [1,11,13,16,26,30,43,46] 
lst2 = [11,27,41]

lst2 = [a + sum(a>=b for b in lst1) for a in lst2]
print("I2 =", lst2)

Output

I2 = [13, 32, 47]

Note: "Python variables should begin with lowercase letters (preferably ones that aren’t easily mistaken for numbers like 1)" as @Chris says.

Answered By: codester_09

use a counter to see the number and their frequency which is less than current, so to avoid the repetiiton calculation

from collections import Counter

I1=[1,11,13,16,26,30,43,46]
I2=[11,27,41]

c1 = Counter(I1)
result = []

for i in I2:
    val = sum(j for v, j in c1.items() if v<=i) + i
    result.append(val)
print(result) # 13 32 47
Answered By: sahasrara62

I am surprised thta nobody mentioned numpy masking yet.

  • data1 <= item will give you an array of booleans showing where that condition is true/false.
  • (data1 <= item).sum() takes advantage of how booleans sum to integers in python to count the number of true items. You could use len(data1[(data1 <= item)]) but it’s longer.
  • We do that for each item in your second array.
import numpy as np

data1 = np.array([1, 11, 13, 16, 26, 30, 43, 46])
data2 = np.array([11, 27, 41])

smaller_counts = np.array([(data1 <= item).sum() for item in data2])
# >>> [2 5 6]
result = data2 + smaller_counts
# >>> [13 32 47]
Answered By: Guimoute

If I1 is always sorted and could be very large, you could use binary search for better performance, with the bisect module:

>>> import bisect
>>> [x + bisect.bisect_right(I1, x) for x in I2]
[13, 32, 47]

Thanks to Psidom for posting this solution in a comment.

Answered By: wjandrea
Categories: questions Tags: ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.