numpy all() evaluating incorrectly - python

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.

Related

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 does this function return non negative numbers?

In [20]: def relu(x):
...: return (x>0) * x
...:
Is that because in Python, True is interpreted as 1 while False as 0 implicitly?
False is just a keyword that means int equal to 0. Same for True and 1.

What is the best way to check if all bits are 1?

I thought this would be easy due to ~, but ~ just returns a negative value of 2^x rather than 0.
You can modify a standard bithack for checking if a number is a power of 2 (numbers one less than a power of 2 are all 1s), with a special case check for zero:
def allOnes(n):
return ((n+1) & n == 0) and (n!=0)
print allOnes(255)
print allOnes(158)
print allOnes(0)
print allOnes(-1)
print allOnes(-2)
Output:
True
False
False
True
False
The easiest way would be to check if 0 present in bin(n). Here are some examples:
Number having all 1's:
>>> n=15
>>> bin(n)
'0b1111'
>>> bin(n)[2:]
'1111'
>>> '0' in bin(n)[2:]
False
Number having 1 or more 0's:
>>> n=5
>>> bin(n)
'0b101'
>>> bin(n)[2:]
'101'
>>> '0' in bin(n)[2:]
True
Most of the languages used MSB (most significant bit) as signed value bit. For example 00000001 in binary is 1 in decimal and 10000011 in binary as -125 in decimal (because of MSB is 1 (-128) & 00000011 is 3 in decimal (-128 + 3 = -125)).
Therefore a binary number whose all bits are 1 is equivalent to -1 in decimal.
So simply if the byte_value is a signed integer,
if(byte_value = -1)
{
printf("All One's");
}
else
{
printf("All Not One's");
}
Otherwise
if(byte_value = 255)
{
printf("All One's");
}
else
{
printf("All Not One's");
}
What you probably want is the XOR (^) operator, and not the bitwise NOT (~) operator you tried (since that just reverts every bit). Since you mentioned the ~ operator as your initial approach, I assume you want to find out if all bits are 1 in an integer by comparing with an integer with all 1's. Perhaps you are optimising for speed.
The XOR operator will return a 1 only when either of the bits in the operands are 1. Consequently, it will give a 1 wherever any of the bits are 0.
>>> 100 ^ 000
100
>>> 100 ^ 100
0
>>> 111 ^ 101
10
>>> 111 ^ 111
0
(As you see the resulting integer is not left padded, but it doesn't matter for our purposes.)
The only 'gotcha' is that you need to know the amount of bits in your number in advance.
Then you could check if all bits in it are 1's, by seeing if the resulting number is anything above 0. If it is, then you know not all bits are 1.
Example:
someNumberWithThreeBits ^ 111 == 0 will return True whenever all bits in someNumberWithThreeBits are 1, and false otherwise.
PS: Please note that 000 ^ 000 would also return 0. But you won't encounter that in this case, unless you decide to compare against 000 instead of 111.
Building on #samgak's answer in response to #Martjin Pieters's comment about specific integer sizes, if the requirement is that all bits for a specific size are 1, then our test needs to be modified. Imagine, for example, that we want to test that a nibble-sized integer is all 1 in binary representation:
In [2]: def all_ones_nibble(to_test: int) -> bool:
...: assert 0 <= to_test < (1 << 4)
...: # bin(1 << 4) == "0b10000", therefore bin((1 << 4) - 1) == "0b1111"
...: return to_test == (1 << 4) - 1
...:
In [3]: all_ones_nibble(int("0", base=2))
Out[3]: False
In [4]: all_ones_nibble(int("1", base=2))
Out[4]: False
In [5]: all_ones_nibble(int("1111", base=2))
Out[5]: True
Of course, it's a bit silly to limit ourselves to nibbles, so let's generalize to arbitrary sizes:
In [6]: def all_ones_for_size(to_test: int, size: int) -> bool:
...: return to_test == (1 << size) - 1
...:
In [7]: all_ones_for_size(int("1111", base=2), 4)
Out[7]: True
In [8]: all_ones_for_size(int("11111111", base=2), 8)
Out[8]: True
In [9]: all_ones_for_size(int("11111110", base=2), 8)
Out[9]: False
Finally, just for fun, let's use #riteshtch's technique to achieve the same result:
In [10]: def all_ones_for_size_using_strs(to_test: int, size: int) -> bool:
...: # NOTE: using a format string obviates the need to shave off "0b".
...: # For example, f"{int('1111', base=2):b}" == "1111", whereas
...: # bin(int("1111", base=2)) == "0b1111"
...: as_bin_str = f"{to_test:b}"
...: return len(as_bin_str) == size and not "0" in as_bin_str
...:
In [11]: all_ones_for_size_using_strs(int("11111110", base=2), 8)
Out[11]: False
In [12]: all_ones_for_size_using_strs(int("11111111", base=2), 8)
Out[12]: True
In [13]: all_ones_for_size_using_strs(int("1111", base=2), 8)
Out[13]: False
Note that this answer uses python 3 with type annotations, which will not work with python 2.7, but as python 2 has long-since been sunsetted, hopeful future viewers will find the modern code more useful.

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)

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

>>> 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

Categories

Resources