Numpy: Why is numpy.array([2]).any() > 1 False? - python

>>> import numpy
>>> numpy.array([2]) > 1
array([ True], dtype=bool)
>>> numpy.array([2]).any() > 1
False
Shouldn't any() test all elements of the array and return True?

It does return True. But (True > 1) == False. While the first part is 2 > 1 which of course is True.
As others posted, you probably want:
(numpy.array([2]) > 1).any()

Perhaps you are confusing it with this
>>> (numpy.array([2]) > 1).any()
True

Related

bitwise AND ini python for comparison

>>> i=5
>>> i>4 & i<5
True
>>> i>4 and i<5
False
I am not able to understand how bitwise AND is used here? The second statement can be understood as 5 is not less than 5, hence it returns false. Can someone throw some light on the first statement?
I have done a bit of experimentation in the python shell and i believe that i know what is going on here. I ran:
>>> 5>4 & 5<5
True
>>> 1 & 0
0
>>> True & False
False
>>> (5>4) & (5<5)
False
>>> (5>4 & 5)<5
True
So I believe what is happening is it is performing (5>4 & 5)<5 instead of (5>4) & (5<5)
& applies before > which applies before and
a > b and a > c, it's parsed as (a > b) and (a > c)
a > b & a > c, it's parsed as a > (b & a) > c

Numpy Array Element-Comparison to Float64

I am trying to return an array (element-wise) of True/False values on a numpy array comparsion to a float64 static variable. Input and desired output array is 1x10 (column x row)
array = np.random.randint(10, size=(10,1))
Attempt 1:
bool = np.any((array >= min)&(array <= max))
Attempt 2:
bool = np.logical_and((array >= min),(array <= max))
Attempt 3:
bool = np.any([(array >= min)&(array <= max)])
Attempt 4:
bool = np.array(np.any([(array >= min)&(array <= max)]))
All four of the above methods produce this output in the interpreter
print(bool) = True
When desired output looks something like:
print(bool) = [True
False
True
True
False
False
True
False
False
True]
Thank you in advance for any insight you can provide me!
you can use .ravel() to get your output in the desired shape.
try this:
import numpy as np
array = np.random.randint(10, size=(10, 1))
min = 2.2
max = 6.6
result = ((array >= min) & (array <= max)).ravel()
print(result)
Output (example, as it is random):
[False True True True True True False False False True]

Why is Z < Z > Z (with Z integer array) an illegal expression in numpy? [duplicate]

a < b < c is an chained expression in Python, and it looks like it works on objects with appropriate comparison operators defined, but it doesn't work on numpy arrays. Why?
import numpy as np
class ContrarianContainer(object):
def __init__(self, x):
self.x = x
def __le__(self, y):
return not self.x <= y
def __lt__(self, y):
return not self.x < y
def __ge__(self, y):
return not self.x >= y
def __gt__(self, y):
return not self.x > y
def __eq__(self, y):
return not self.x == y
def __ne__(self, y):
return not self.x != y
numlist = np.array([1,2,3,4])
for n in numlist:
print 0 < n < 3.5
for n in numlist:
print 0 > ContrarianContainer(n) > 3.5
print 0 < numlist < 3.5
this prints:
True
True
True
False
True
True
True
False
---------------------------------------------------------------------------
ValueError Traceback (most recent call last)
<ipython-input-187-277da7750148> in <module>()
4 for n in numlist:
5 print 0 < n < 3.5
----> 6 print 0 < numlist < 3.5
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
0 < numlist < 3.5
Is equivalent to:
(0 < numlist) and (numlist < 3.5)
except that numlist is only evaluated once.
The implicit and between the two results is causing the error
So the docs say:
Formally, if a, b, c, ..., y, z are expressions and op1, op2, ..., opN are comparison operators, then a op1 b op2 c ... y opN z is equivalent to a op1 b and b op2 c and ... y opN z, except that each expression is evaluated at most once.
and
(but in both cases z is not evaluated at all when x < y is found to be false).
For a scalar
In [20]: x=5
In [21]: 0<x<10
Out[21]: True
In [22]: 0<x and x<10
Out[22]: True
But with an array
In [24]: x=np.array([4,5,6])
In [25]: 0<x and x<10
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
This ValueError arises when a numpy boolean is used in a context that expects a scalar boolean.
In [26]: (0<x)
Out[26]: array([ True, True, True], dtype=bool)
In [30]: np.array([True, False]) or True
...
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
In [33]: if np.array([True, False]): print('yes')
ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
It evaluates the 0<x, but doesn't even get to evaluating the x<10, because it can't use the resulting boolean array in a or/and context. numpy has defined | and &, but not or or and.
In [34]: (0<x) & x<10
Out[34]: array([ True, True, True], dtype=bool)
When we use 0 < x <10 we are implicitly expecting to evaluate a vectorized version of the scalar chained expression.
In [35]: f = np.vectorize(lambda x: 0<x<10, otypes=[bool])
In [36]: f(x)
Out[36]: array([ True, True, True], dtype=bool)
In [37]: f([-1,5,11])
Out[37]: array([False, True, False], dtype=bool)
Note that attempting to apply chaining to a list doesn't even get past the first <:
In [39]: 0 < [-1,5,11]
TypeError: unorderable types: int() < list()
This set of expressions indicates that the & operator has precedence over the < operator:
In [44]: 0 < x & x<10
ValueError ...
In [45]: (0 < x) & x<10
Out[45]: array([ True, True, True], dtype=bool)
In [46]: 0 < x & (x<10)
Out[46]: array([False, True, False], dtype=bool)
In [47]: 0 < (x & x)<10
ValueError...
So the safe version is (0 < x) & (x<10), making sure that all < are evaluated before the &.
edit
Here's a further example that confirms the short-cut and evaluation:
In [53]: x=2
In [54]: 3<x<np.arange(4)
Out[54]: False
In [55]: 1<x<np.arange(4)
Out[55]: array([False, False, False, True])
When 3<x is False, it returns that, without further evaluation.
When it is True, it goes on to evaluate x<np.arange(4), returning a 4 element boolean.
Or with a list that doesn't support < at all:
In [56]: 3<x<[1,2,3]
Out[56]: False
In [57]: 1<x<[1,2,3]
Traceback (most recent call last):
File "<ipython-input-57-e7430e03ad55>", line 1, in <module>
1<x<[1,2,3]
TypeError: '<' not supported between instances of 'int' and 'list'

numpy all() evaluating incorrectly

My code should stop when all the values of my array are greater than 100. I am using np.all() to evaluate the condition. It looks like the condition is met, but np.all() seems to be incorrectly evaluating. What am I missing? Python 2.7.8 on OS 10.8.5.
(Pdb) ratio_J_a
array([ 250.44244741, 186.92848637, 202.67726408, 143.01112845,
132.95878384, 176.49130164, 178.9892571 , 118.07516559,
205.59639112, 183.64142204])
(Pdb) np.all(ratio_J_a) > 100.
False
(Pdb) np.all(ratio_J_a) < 100.
True
I think you should have:
In [5]: import numpy as np
In [6]: ratio_J_a = np.array([ 250.44244741, 186.92848637, 202.67726408, 143.01112845,
...: 132.95878384, 176.49130164, 178.9892571 , 118.07516559,
...: 205.59639112, 183.64142204])
In [7]: print(np.all(ratio_J_a > 100.))
True
In [8]: print(np.all(ratio_J_a < 100.))
False
And just in case, you are actually wondering why you got this:
(Pdb) np.all(ratio_J_a) > 100.
False
(Pdb) np.all(ratio_J_a) < 100.
True
The reason is that np.all(ratio_J_a) evaluates to true, which is treated as one, e.g.
In [17]: "{}".format(np.all(ratio_J_a))
Out[17]: 'True'
In [18]: "{:d}".format(np.all(ratio_J_a))
Out[18]: '1'
Thus, in your case you are actually doing this:
(Pdb) 1 > 100.
False
(Pdb) 1 < 100.
True
numpy.all tests whether all array elements along a given axis evaluate to True.
>>> import numpy as np
>>> ratio_J_a = np.array([
... 250.44244741, 186.92848637, 202.67726408, 143.01112845,
... 132.95878384, 176.49130164, 178.9892571 , 118.07516559,
... 205.59639112, 183.64142204
... ])
>>> np.all(ratio_J_a > 100)
True
>>> np.all(ratio_J_a < 100)
False
Why you got wrong result:
np.all(ratio_J_a) is evaluated as True because non-zero numbers are treated as a truth value. And True is equal to 1. 1 > 100 is False, 1 < 100 is True.

python, how to write conditions in a function?

How to write conditions in a function (k_over_iq)?
dt_for_all_days_np=a numpy array of numbers.
def k_over_iq(dt):
if dt !=0:
return 0.7*(1-e**(-0.01*dt**2.4))
else:
return 1
k_over_iq_i=k_over_iq(dt_for_all_days_np)
I get the following error:
if dt !=0: ValueError: The truth value of an array with more than one element is ambiguous. Use a.any() or a.all()
if dt != 0: won't work if dt is a numpy array. The if tries to get a single boolean out of the array, and as the error message warns, that's ambiguous: is array([True, False]) True or False?
To get around that in a vectorized fashion, two common ways are to use where or to use boolean indexing to patch.
Method #1, np.where
>>> dt = np.array([0,1,2,3])
>>> np.where(dt != 0, 0.7*(1-np.exp(-0.01*dt**2.4)), 1)
array([ 1. , 0.00696512, 0.03598813, 0.09124601])
This uses the function whenever dt != 0:
>>> dt != 0
array([False, True, True, True], dtype=bool)
and 1 otherwise.
Method #2: boolean indexing to patch
Compute the function everywhere and then fix the values that are wrong.
>>> b = 0.7*(1-np.exp(-0.01*dt**2.4))
>>> b
array([ 0. , 0.00696512, 0.03598813, 0.09124601])
>>> b[dt == 0] = 1
>>> b
array([ 1. , 0.00696512, 0.03598813, 0.09124601])
Indentation is the problem in your function.
I recommend you reading this: Python: Myths about Indentation
def k_over_iq(dt):
if dt !=0:
return 0.7*(1-e**(-0.01*dt**2.4))
else:
return 1
k_over_iq_i=k_over_iq(dt_for_all_days_np)

Categories

Resources