Finding if the values in one list, are found between values of another sub-list

Question:

I know the title is a bit confusing, it was hard for me to put a title to this. I’ll give an example to what I need I think it will be clear.

I have a list of coefficients (contains 15 values), let’s call it listA:

Coefficients:  [ 0.04870086  0.57480212  0.89015539  2.3233615   4.55812396  7.13551459
 -1.08155996  2.17696328 -2.63679501 -2.33568303  1.44485836  2.57565872
  1.49871307  0.26896593  4.91618077  4.40561426]

And I have a list of lists (contains 15 sub-lists). Each sub-list is made of two numbers, let’s call it listB:

    [[-0.006242951417219811, 0.2695363035421434], [0.18216832098326075, 1.2135053544677805]
, [-5.7767682655295856, 8.644974491878234], [-2.6175178748619965, 11.350843901384977], 
[-3.5832555764006813, 19.889930736681176], [-18.98605217513358, -0.44537447407901887],
 [-4.66448539414492, 10.687900677104983], [-8.502439858318859, 3.8546296063721726], 
[-17.319599857758103, 18.476221095928576], [-5.287099091734136, 7.830321030743221], 
[-11.37116751629717, 24.648615759994385], [-8.133549393916292, 5.702535573546525], 
[-10.412791226300737, 13.0758676055572], [-3.5332459196432042, 13.790340644751073], 
[1.1737906639770186, 9.66211063676472]]

What I want to do is check if the values in listA are found between the two numbers in the corresponding sub-list, and present that in a vector of boolian values or something like that.

For example, listA[0] is 0.04870086 and yes it can be found in listB[0] which is [-0.006242951417219811, 0.2695363035421434] (between the values). Then the same for listA[1] and listB[1] and so on.

Could you guys help me do this with a for loop or something? and then store the results in a vector of TrueFalse that I can show?

Thanks!

Asked By: Kev

||

Answers:

I am not really shure of your goal. There are at least two ways to interprete your question.

In general I will use the following lists based on your question (repeated in code notation to ease copy and paste)

coefficients = [0.04870086, 0.57480212, 0.89015539, 2.3233615, 4.55812396, 7.13551459,
                -1.08155996, 2.17696328, -2.63679501, -2.33568303, 1.44485836, 2.57565872,
                1.49871307, 0.26896593, 4.91618077]
ranges = [
    [-0.006242951417219811, 0.2695363035421434], [0.18216832098326075, 1.2135053544677805],
    [-5.7767682655295856, 8.644974491878234], [-2.6175178748619965, 11.350843901384977],
    [-3.5832555764006813, 19.889930736681176], [-18.98605217513358, -0.44537447407901887],
    [-4.66448539414492, 10.687900677104983], [-8.502439858318859, 3.8546296063721726],
    [-17.319599857758103, 18.476221095928576], [-5.287099091734136, 7.830321030743221],
    [-11.37116751629717, 24.648615759994385], [-8.133549393916292, 5.702535573546525],
    [-10.412791226300737, 13.0758676055572], [-3.5332459196432042, 13.790340644751073],
    [1.1737906639770186, 9.66211063676472]]

So the two scenarios I came up with are:


You give the example that lista[0] shall be in listb[0] and then check for the next index in both cases. My extracted scenario is, that for each coefficient you would want to have a matching range.

import sys
import matplotlib.pyplot as plt

def in_range(idx: int) -> int:
    return int(ranges[idx][0] <= coefficients[idx] <= ranges[idx][1])

if len(coefficients) > len(ranges):
    print(f"Not enough ranges ({len(ranges)}) for the given coefficients ({len(coefficients)})")
    sys.exit(1)

contained = [in_range(i) for i in range(len(coefficients))]
plt.plot(contained, '*')
plt.minorticks_off()
plt.show()

enter image description here


The second scenario is that you want to have each coefficient checked against each range. The result would be a matrix:

import matplotlib.pyplot as plt

def in_range(coeff_id: int, range_idx: int) -> int:
    return int(ranges[range_idx][0] <= coefficients[coeff_id] <= ranges[range_idx][1])

def in_any_range(coeff_id: int) -> list:
    return [in_range(coeff_id, r) for r in range(len(ranges))]

contained = [in_any_range(i) for i in range(len(coefficients))]
plt.imshow(contained, cmap='gray')
plt.show()

enter image description here

Answered By: Cpt.Hook

I am a fan of Pandas so will toss in a version based on that package. Note that I interpreted the question as an item by item test and not as a cross join.

Starting from the arrays defined in Cpt.Hook‘s answer…

import pandas as pd

# Create a dataframe from ranges 
df = pd.DataFrame(data=ranges, columns=['low', 'high'])

# Add coefficients separately
df['coefficients'] = coefficients

# Check if they are in range
df['in_range'] = df['coefficients'].between(df['low'], df['high'])

df prints out as…


     low         high       coefficient in_range
0   -0.006243    0.269536   0.048701    True
1    0.182168    1.213505   0.574802    True
2   -5.776768    8.644974   0.890155    True
3   -2.617518   11.350844   2.323361    True
4   -3.583256   19.889931   4.558124    True
5  -18.986052   -0.445374   7.135515   False
6   -4.664485   10.687901  -1.081560    True
7   -8.502440    3.854630   2.176963    True
8   -17.319600  18.476221  -2.636795    True
9   -5.287099    7.830321  -2.335683    True
10 -11.371168   24.648616   1.444858    True
11  -8.133549    5.702536   2.575659    True
12 -10.412791   13.075868   1.498713    True
13  -3.533246   13.790341   0.268966    True
14   1.173791    9.662111   4.916181    True

df['in_range'] is the vector of booleans (aka Series) you were looking for.

Answered By: The Lazy Graybeard
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.