With focus on performance and using two methods few aproaches could be added. One method would be to get the boolean array of valid ones and converting to int
datatype with .astype() method
. Another way could involve using np.where
that lets us select between 0
and 1
based on the same boolean array. Thus, essentially we would have two methods, one that harnesses efficient datatype conversion and another that uses selection criteria. Now, the boolean array could be obtained in two ways - One using simple comparison and another using np.logical_and
. So, with two ways to get the boolean array and two methods to convert the boolean array to int
array, we would end up with four implementations as listed below -
out1 = ((aa > 0.5) & (bb > 0.5)).astype(int) out2 = np.logical_and(aa > 0.5, bb > 0.5).astype(int) out3 = np.where((aa > 0.5) & (bb > 0.5), 1, 0) out4 = np.where(np.logical_and(aa > 0.5, bb > 0.5), 1, 0)
You can play around with the datatypes to use less precision types, which shouldn't hurt as we are setting the values to 0
and 1
anyway. The benefit should be noticeable speedup as it leverages memory efficiency. We could use int8
, uint8
, np.int8
, np.uint8
types. Thus, the variants of the earlier listed approaches using the new int
datatypes would be -
out5 = ((aa > 0.5) & (bb > 0.5)).astype('int8')
out6 = np.logical_and(aa > 0.5, bb > 0.5).astype('int8')
out7 = ((aa > 0.5) & (bb > 0.5)).astype('uint8')
out8 = np.logical_and(aa > 0.5, bb > 0.5).astype('uint8')
out9 = ((aa > 0.5) & (bb > 0.5)).astype(np.int8)
out10 = np.logical_and(aa > 0.5, bb > 0.5).astype(np.int8)
out11 = ((aa > 0.5) & (bb > 0.5)).astype(np.uint8)
out12 = np.logical_and(aa > 0.5, bb > 0.5).astype(np.uint8)
Runtime test (as we are focusing on performance with this post) -
In[17]: # Input arrays ...: aa = np.random.rand(1000, 1000) ...: bb = np.random.rand(1000, 1000) ...: In[18]: % timeit((aa > 0.5) & (bb > 0.5)).astype(int) ...: % timeit np.logical_and(aa > 0.5, bb > 0.5).astype(int) ...: % timeit np.where((aa > 0.5) & (bb > 0.5), 1, 0) ...: % timeit np.where(np.logical_and(aa > 0.5, bb > 0.5), 1, 0) ...: 100 loops, best of 3: 9.13 ms per loop 100 loops, best of 3: 9.16 ms per loop 100 loops, best of 3: 10.4 ms per loop 100 loops, best of 3: 10.4 ms per loop In[19]: % timeit((aa > 0.5) & (bb > 0.5)).astype('int8') ...: % timeit np.logical_and(aa > 0.5, bb > 0.5).astype('int8') ...: % timeit((aa > 0.5) & (bb > 0.5)).astype('uint8') ...: % timeit np.logical_and(aa > 0.5, bb > 0.5).astype('uint8') ...: ...: % timeit((aa > 0.5) & (bb > 0.5)).astype(np.int8) ...: % timeit np.logical_and(aa > 0.5, bb > 0.5).astype(np.int8) ...: % timeit((aa > 0.5) & (bb > 0.5)).astype(np.uint8) ...: % timeit np.logical_and(aa > 0.5, bb > 0.5).astype(np.uint8) ...: 100 loops, best of 3: 5.6 ms per loop 100 loops, best of 3: 5.61 ms per loop 100 loops, best of 3: 5.63 ms per loop 100 loops, best of 3: 5.63 ms per loop 100 loops, best of 3: 5.62 ms per loop 100 loops, best of 3: 5.62 ms per loop 100 loops, best of 3: 5.62 ms per loop 100 loops, best of 3: 5.61 ms per loop In[20]: % timeit 1 * ((aa > 0.5) & (bb > 0.5)) # @BPL 's vectorized soln 100 loops, best of 3: 10.2 ms per loop
What about this?
import numpy as np
aa = np.random.rand(5, 5)
bb = np.random.rand(5, 5)
print aa
print bb
cc = 1 * ((aa > 0.5) & (bb > 0.5))
print cc
when element of aa and bb at index i is exceed than 0.5 then new array have 1 at index i
aa = np.random.rand(5, 5) bb = np.random.rand(5, 5) new_arr = [] for i in range(5): for j in range(5): if aa[i] > 0.5 and bb[i] > 0.5: new_arr[i] = 1 else: new_arr[i] = "any Value You want
In this article we will discuss how to select elements or indices from a Numpy array based on multiple conditions., Similar to arithmetic operations when we apply any comparison operator to Numpy Array, then it will be applied to each element in the array and a new bool Numpy Array will be created with values True or False. Suppose we have a Numpy Array i.e. ,Here we need to check two conditions i.e. element > 5 and element < 20. But python keywords and , or doesn’t works with bool Numpy Arrays. Instead of it we should use & , | operators i.e. ,Click below to consent to the above or make granular choices. Your choices will be applied to this site only. You can change your settings at any time, including withdrawing your consent, by using the toggles on the Cookie Policy, or by clicking on the manage consent button at the bottom of the screen.
Similar to arithmetic operations when we apply any comparison operator to Numpy Array, then it will be applied to each element in the array and a new bool Numpy Array will be created with values True or False.
Suppose we have a Numpy Array i.e.
#Create an Numpy Array containing elements from 5 to 30 but at equal interval of 2
arr = np.arange(5, 30, 2)
[5 7 9 11 13 15 17 19 21 23 25 27 29]
Let’s apply < operator on above created numpy array i.e.
# Comparison Operator will be applied to all elements in array boolArr = arr < 10
Here we need to check two conditions i.e. element > 5 and element < 20. But python keywords and , or doesn’t works with bool Numpy Arrays. Instead of it we should use & , | operators i.e.
#Select elements from Numpy Array which are greater than 5 and less than 20
newArr = arr[(arr > 5) & (arr < 20)]
Contents of Numpy array newArr are,
[7 9 11 13 15 17 19]
An array with elements from x where condition is True, and elements from y elsewhere.,Return elements chosen from x or y depending on condition.,When only condition is provided, this function is a shorthand for np.asarray(condition).nonzero(). Using nonzero directly should be preferred, as it behaves correctly for subclasses. The rest of this documentation covers only the case where all three arguments are provided.,Values from which to choose. x, y and condition need to be broadcastable to some shape.
[xv
if c
else yv
for c, xv, yv in zip(condition, x, y)
]
>>> a = np.arange(10) >>> a array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) >>> np.where(a < 5, a, 10 * a) array([0, 1, 2, 3, 4, 50, 60, 70, 80, 90])
>>> np.where([ [True, False], [True, True] ], ...[ [1, 2], [3, 4] ], ...[ [9, 8], [7, 6] ]) array([ [1, 8], [3, 4] ])
>>> x, y = np.ogrid[: 3,: 4] >>> np.where(x < y, x, 10 + y) # both x and 10 + y are broadcast array([ [10, 0, 0, 0], [10, 11, 1, 1], [10, 11, 12, 2] ])
>>> a = np.array([ [0, 1, 2], ...[0, 2, 4], ...[0, 3, 6] ]) >>> np.where(a < 4, a, -1) # - 1 is broadcast array([ [0, 1, 2], [0, 2, -1], [0, 3, -1] ])
JavaScript seems to be disabled in your browser. You must have JavaScript enabled in your browser to utilize the functionality of this website.
import numpy as np
the_array = np.array([49, 7, 44, 27, 13, 35, 71])
an_array = np.where(the_array > 30, 0, the_array)
print(an_array)
[0 7 0 27 13 0 0]
import numpy as np
the_array = np.array([49, 7, 44, 27, 13, 35, 71])
an_array = np.where((the_array > 30) & (the_array < 50), 0, the_array)
print(an_array)
[0 7 0 27 13 0 71]
import numpy as np
the_array = np.array([49, 7, 44, 27, 13, 35, 71])
an_array = np.where(the_array > 40, the_array + 5, the_array)
print(an_array)
import numpy as np
the_array = np.array([49, 7, 44, 27, 13, 35, 71])
an_array = np.where(the_array > 25, np.NaN, the_array)
print(an_array)
If the true value and false value are not specified an array (or tuple of arrays if the conditional array is multidimensional) of indices where the condition evaluates to true is returned. If true and false values are specified the result is an array of the same shape as the conditional array with updated values.,Now let’s specify the true and false values. When we do this np.where will return an array of values instead of a tuple of index arrays. Let’s give it a try.,Let’s create a simple 1-dimensional array. This array will be the square of sequential integers. I’ve squared the integers so that the values in the array do not correspond directly to the values of the array indices (that would be a little confusing).,Here we use the same conditional expression (a1d > 5) but specify the result array should have a value of 0 where the condition is true and value of 1 where the condition is false. The result is an array with a value of 1 where a1d is less than 5 and a value of 0 everywhere else.
import numpy as np
a1d = np.square(np.arange(10)) a1d
array([0, 1, 4, 9, 16, 25, 36, 49, 64, 81], dtype = int32)
np.where(a1d > 5)
(array([3, 4, 5, 6, 7, 8, 9], dtype = int64), )
a1d[np.where(a1d > 5)]
Last Updated : 28 Apr, 2022
Output:
[ [1 2 3] [4 5 6] ]