numpy: is there an `allclose(np.array, scalar)`? - python

In numpy you can use the allclose(X, Y) function to check element-wise for approximate equality between two arrays. Moreover, with an expression like X==5 you can check element-wise equality between an array and a scalar.
Is there a function that combines both functionalities?? That is, can compare an array and a scalar for approximate element-wise equality??

The term array or array-like in the numpy documentation mostly indicates that the input is converted to an array with np.asarray(in_arg) or np.asanyarray(in_arg). So if you input a scalar it will be converted to an scalar array:
>>> import numpy as np
>>> np.asarray(5) # or np.asanyarray
array(5)
And the functions np.allclose or np.isclose just do element-wise comparison no matter if the second argument is a scalar array, an array with the same shape or an array that correctly broadcasts to the first array:
>>> import numpy as np
>>> arr = np.array([1,2,1,0,1.00001,0.9999999])
>>> np.allclose(arr, 1)
False
>>> np.isclose(arr, 1)
array([ True, False, True, False, True, True], dtype=bool)
>>> np.isclose(arr, np.ones((10, 6)))
array([[ True, False, True, False, True, True],
[ True, False, True, False, True, True],
[ True, False, True, False, True, True],
[ True, False, True, False, True, True],
[ True, False, True, False, True, True],
[ True, False, True, False, True, True],
[ True, False, True, False, True, True],
[ True, False, True, False, True, True],
[ True, False, True, False, True, True],
[ True, False, True, False, True, True]], dtype=bool)
So no need to find another function that explicitly handles scalars, these functions already correctly work with scalars.

Related

How do I combine multiple NumPy boolean arrays?

I have a two-dimensional (2D) array that contains many one-dimensional (1D) arrays of random boolean values.
import numpy as np
def random_array_of_bools():
return np.random.choice(a=[False, True], size=5)
boolean_arrays = np.array([
random_array_of_bools(),
random_array_of_bools(),
... so on
])
Assume that I have three arrays:
[True, False, True, True, False]
[False, True, True, True, True]
[True, True, True, False, False]
This is my desired result:
[False, False, True, False, False]
How can I achieve this with NumPy?
Use min with axis=0:
>>> boolean_array.min(axis=0)
array([False, False, True, False, False])
>>>
Use .all:
import numpy as np
arr = np.array([[True, False, True, True, False],
[False, True, True, True, True],
[True, True, True, False, False]])
res = arr.all(0)
print(res)
Output
[False False True False False]
try numpy bitwise_and =>
out_arr = np.bitwise_and(np.bitwise_and(in_arr1, in_arr2),in_arr3)

Array of bools to ndarray

I have this array (let's call it my_array) which comes from applying numpy.any:
my_array
array([[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
...,
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True]])
Is there a way to convert this array to a ndarray? I mean, how can I see this:
array([[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
...,
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True],
[ True, True, True, ..., True, True, True]],dtype=bool)
When you show something like that to the IDE, it uses repr(obj), which creates a string representation of the object. Ideally this also means eval(repr(object)) == object. The reason why you don't see the dtype=bool part is that an array comprised fully of booleans is unambiguously boolean. Likewise, an integer array is by default of dtype int32, so that is also excluded. But if you have an integer of some other type, then it will be shown.
>>> np.array([1, 2])
array([1, 2])
>>> np.array([1, 2]).dtype
dtype('int32')
>>> np.array([1, 2], dtype=np.uint8)
array([1, 2], dtype=uint8)
Your result is already in the output you want. And the docs for numpy.any confirm that:
Returns
-------
any : bool or ndarray
A new boolean or `ndarray` is returned unless `out` is specified,
in which case a reference to `out` is returned.
But if you want to make sure everything is right, you can check type(my_array) and my_array.dtype (assuming the object is a numpy array).
>>> a = np.any([[1, 2], [3, 4]], axis=0)
>>> a
array([ True, True])
>>> type(a)
<class 'numpy.ndarray'>
>>> a.dtype
dtype('bool')

Compare a numpy array to each element of another one

A = np.array([5,1,5,8])
B = np.array([2,5])
I want to compare the A array to each element of B. In other words I'm lookin for a function which do the following computations :
A>2
A>5
(array([ True, False, True, True]), array([False, False, False, True]))
Not particularly fancy but a list comprehension will work:
[A > b for b in B]
[array([ True, False, True, True], dtype=bool),
array([False, False, False, True], dtype=bool)]
You can also use np.greater(), which requires the dimension-adding trick that Brenlla uses in the comments:
np.greater(A, B[:,np.newaxis])
array([[ True, False, True, True],
[False, False, False, True]], dtype=bool)

Intersect two boolean arrays for True

Having the numpy arrays
a = np.array([ True, False, False, True, False], dtype=bool)
b = np.array([False, True, True, True, False], dtype=bool)
how can I make the intersection of the two so that only the True values match? I can do something like:
a == b
array([False, False, False, True, True], dtype=bool)
but the last item is True (understandably because both are False), whereas I would like the result array to be True only in the 4th element, something like:
array([False, False, False, True, False], dtype=bool)
Numpy provides logical_and() for that purpose:
a = np.array([ True, False, False, True, False], dtype=bool)
b = np.array([False, True, True, True, False], dtype=bool)
c = np.logical_and(a, b)
# array([False, False, False, True, False], dtype=bool)
More at Numpy Logical operations.

Populate numpy matrix dynamically from array values?

I'm trying to dynamically construct a 2-D matrix with numpy based on the values of an array, like this:
In [113]: A = np.zeros((5,5),dtype=bool)
In [114]: A
Out[114]: array([[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False],
[False, False, False, False, False]], dtype=bool)
In [116]: B = np.array([0,1,3,0,2])
In [117]: B
Out[117]: array([0, 1, 3, 0, 2])
Now, I'd like to use the values of B to assign the first n values of each row to A to True. For this A and B, the correct output would be:
In [118]: A
Out[118]: array([[False, False, False, False, False],
[ True, False, False, False, False],
[ True, True, True, False, False],
[False, False, False, False, False],
[ True, True, False, False, False]], dtype=bool)
The length of B will always equal the number of rows of A, and the the values of B will always be less than or equal to the number of columns of A. The size of A and the values of B are constantly changing, so I need to build these on the fly.
I'm certain that this has a simple(-ish) solution in numpy, but I've spent the last hour banging my head against variations of repeat, tile, and anything else I can think of. Can anyone help me out before I give myself a concussion? :)
EDIT: I'm going to need to do this a lot, so speed will be an issue. The only version that I can come up with for now is something like:
np.vstack([ [True]*x + [False]*(500-x) for x in B ])
but I expect that this will be slow due to the for loop (I would time it if I had anything to compare it to).
How about:
>>> A = np.zeros((5, 7),dtype=bool)
>>> B = np.array([0,1,3,0,2])
>>> (np.arange(len(A[0])) < B[:,None])
array([[False, False, False, False, False, False, False],
[ True, False, False, False, False, False, False],
[ True, True, True, False, False, False, False],
[False, False, False, False, False, False, False],
[ True, True, False, False, False, False, False]], dtype=bool)
(I changed the shape from (5,5) because I was getting confused about which axis was which, and I wanted to make sure I was using the right one.)
[Simplified from (np.arange(len(A[0]))[:,None] < B).T -- if we expand B and not A, there's no need for the transpose.]

Categories