Home > OS >  Number of values within a specific range in Python
Number of values within a specific range in Python

Time:12-11

I have an array T. I am trying to find the number of values within a specified range through T1 but I am getting an error. I present the expected output.

T=np.array([4.7,5.1,2.9])
T1=np.flatnonzero(2<T<3,3<T<4,4<T<5)
print(T1)

The error is

in <module>
    T1=np.flatnonzero(2<T<3,3<T<4,4<T<5)

ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()

The expected output is

T1=[1,0,1]

CodePudding user response:

You need to split the ranges to two and sum the results. You also don't need to use np.flatnonzero here, it's not really connected to what you are doing

T1 = ((2 < T) & (T < 3)).sum(), ((3 < T) & (T < 4)).sum(), ((4 < T) & (T < 5)).sum()
print(T1) # (1, 0, 1)

CodePudding user response:

Why do you expect this to work?

  1. It breaks in 2<T<3. You can't use this kind of syntax in numpy. You should to replace 2<T<3 with (2<T) & (T<3) which is equivalent of np.logical_and. So you need the truth value of two boolean arrays (2<T) AND (T<3) element-wise as it said in docummentation.
  2. np.flatnonzero takes one single argument. If you want to plug in several conditions, use | (or np.logical_or) to get the truth value of two boolean arrays arr1 OR arr2 element-wise.
cond1 = (2<T) & (T<3) 
cond2 = (3<T) & (T<4) 
cond3 = (4<T) & (T<5) 

Number of conditions fulfilled for each value:

>>> np.sum([cond1, cond2, cond3], axis=0)
array([1, 0, 1])

Arrays of values that satisfies each condition:

>>> T[cond1], T[cond2], T[cond3]
(array([2.9]), array([], dtype=float64), array([4.7]))

Arrays of indices of values that satisfies each condition:

>>> np.flatnonzero(cond1), np.flatnonzero(cond2), np.flatnonzero(cond3)
(array([2], dtype=int64), array([], dtype=int64), array([0], dtype=int64))

CodePudding user response:

  • flatnonzero has nothing to do with what you want.
  • Furthermore, the error 'The truth value of an array with more than one element is ambiguous' comes from the double condition 2<T<3: you need to separate it into 2 conditions: (2<T) & (T<3).
  • T[(2<T) & (T<3)] will yield an array of the values of T respecting the conditions.

Thus, if you need to count the elements of T that are between 2 and 3, you can do:

len(T[(2 <T) & (T < 3)])

To obtain what you want, you could then do this:

Ranges = [(2,3),(3,4),(4,5)]
T1 = [len(T[(a < T) & (T < b)]) for a,b in Ranges]

print(T1)
# [1, 0, 1]

To print the actual values fitting the criteria, you can do:

T2 = [list(T[(a < T) & (T < b)]) for a,b in Ranges]

print(T2)
# [[2.9], [], [4.7]]

To get the corresponding indices, we finally have a use for flatnonzero:

T3 = [list(np.flatnonzero((a < T) & (T < b))) for a,b in Ranges]

print(T3)
# [[2], [], [0]]
  • Related