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?
- It breaks in
2<T<3
. You can't use this kind of syntax innumpy
. You should to replace2<T<3
with(2<T) & (T<3)
which is equivalent ofnp.logical_and
. So you need the truth value of two boolean arrays (2<T) AND (T<3) element-wise as it said in docummentation. np.flatnonzero
takes one single argument. If you want to plug in several conditions, use|
(ornp.logical_or
) to get the truth value of two boolean arraysarr1
ORarr2
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]]