Check numpy array if a row contains at least one false - python

I have an array 2*n of True and False boolean.
array([[False, True],
[False, True],
[False, True],
...,
[False, True],
[False, True],
[False, True]])
What I want is a new vector, can be in another array that has False if any of the two values are False.
I can create a loop and check each value in the row, and make a new vector. but I'm guessing it's slow
boidx = np.empty(len(minindex), dtype=bool)
for idx in range(len(minindex)):
if minindex[idx,0] and minindex[idx,1]:
boidx[idx]=True
else:
boidx[idx]=False
but this is long and not pythonic.
The array is either 2n or 4n. so it should cover those options (my for loop does not)
but if needed, two solutions with an if for size is doable.
I also tried to use numpy.isin() command. but it works for each cell. I need per row.

As an answer already pointed out, you can use numpy.all() to solve it.
A simpler formulation without any loop would be:
np.all(minindex, axis=1)

If I understand correctly, a pythonic solution could use numpy.all:
import numpy as np
minindex = np.array([[False, True],
[False, True],
[True, True],
[True, False],
[False, True],
[False, False],
[False, False],
[True, True]
boidx = np.array([np.all(i) for i in minindex])
and you get:
[False False True False False False False True]
Another solution could be the use of prod:
boidx = np.array([bool(i.prod()) for i in minindex])
and you get the same result.
As suggested by #Jianyu, this way should be definitely faster:
boidx = np.all(minindex, axis=1)

Related

Is there a fast way to create a bool matrix from another matrix in python?

i would like to know if there is a faster way, not O(n^2), to create a bool matrix out of an integer nxn-matrix.
Example:
given is the matrix:
matrix_int = [[-5,-8,6],[4,6,-9],[7,8,9]]
after transformation i want this:
matrix_bool = [[False,False,True],[True,True,False],[True,True,True]]
so all negative values should be False and all positive values should be True.
The brute force way is O(n^2) and this is too slow for me, too you have any ideas how to make this faster?
matrix_int = [[-5,-8,6],[4,6,-9],[7,8,9]]
matrix_int = np.array(matrix_int)
bool_mat = matrix_int > 0
result:
array([[False, False, True],
[ True, True, False],
[ True, True, True]])
matrix_int = [[-5,-8,6],[4,6,-9],[7,8,9]]
matrix_bool = [[num > 0 for num in row] for row in matrix_int]
# [[False, False, True], [True, True, False], [True, True, True]]

How to return True if two-dimensional array in python has at least one True

I'm trying to write a code which checks if 2D-array (consists of only boolean) has at least one True and return True if there is at least one True.
I tried using all() function but couldn't come up with a solution. I assume what I need is opposite of what all() function does.
>>> array1 = [[True, False], [False, False]]
>>> all([all(row) for row in array1)
False # This should be True
>>> array2 = [[False, False], [False, False]]
>>> all([all(row) for row in array2)
False # This is correct but this and array with all True is only working case.
For array1 = [[True, False], [False, False]], I expect the output to be True since there is one True at array1[0][0].
def has_true(arr):
return any(any(row) for row in arr)
In [7]: array1 = [[True, False], [False, False]]
In [8]: array2 = [[False, False], [False, False]]
In [9]: has_true(array1)
Out[9]: True
In [10]: has_true(array2)
Out[10]: False
this answer is using generators so it will return upon finding the first True value without running over the whole matrix. in addition it will use O(1) space
edit: removed unnecessary code
use any() instead of all(). all() return true if all items in an iterable object are true.
any() Returns True if any item in an iterable object is true.
A much shorter approach is to chain the lists together using itertools.chain and apply any on them
from itertools import chain
def has_true(arr):
return any(chain(*arr))
print(has_true([[True, False], [False, False]]))
print(has_true([[False, False], [False, False]]))
The output will be
True
False

Generate all possible values for variables with recursion

I'm creating a truth table with Python and I have done so iteratively without any hassle, but I'm trying to figure out how to generate all possible values of True and False, for any number of variable recursively.
Starting with a list like: [[True], [False]]
I need to be able to generate a list like:
[[True, True, True],
[True, True, False],
[True, False, True],
[True, False, False],
[False, True, True],
[False, True, False],
[False, False, True],
[False, False, False]]
where every list is a row in the truth table.
Based on this, you go through and evaluate each row, appending the value of true or false to the end of each list based on the expression being evaluated.
I have already solved the problem iteratively, but doing it recursively doesn't make any sense to me. I've always thought of recursion as starting large and becoming small (reducing toward the base case). Like in merge sort. Not the other way around.
I cannot use anything like itertools.
The hint in the assignment is "Tips: You can use the following recursive algorithm to create all combinations of variables for the truth table:
Base case: For a single variable, the list of all combinations is [ [True], [False] ]
Recursive case: each element in the list (which is itself a list), is replaced with two lists, one with True appended to it, and one with False appended to it."
The algorithm doesn't make sense to me.
The following recursive implementation will work. Note that you can have an even simpler base case:
def bool_combs(n):
if not n:
return [[]]
result = []
for comb in bool_combs(n-1):
result.append(comb + [True])
result.append(comb + [False])
return result
>>> bool_combs(1)
[[True], [False]]
>>> bool_combs(2)
[[True, True], [True, False], [False, True], [False, False]]
>>> bool_combs(3)
[[True, True, True], [True, True, False], [True, False, True], [True, False, False], [False, True, True], [False, True, False], [False, False, True], [False, False, False]]

too many indices for array when using np.where

I have the code:
a=b=np.arange(9).reshape(3,3)
c=np.zeros(3)
for x in range(3):
c[x]=np.average(b[np.where(a<x+3)])
The output of c is
>>>array([ 1. , 1.5, 2. ])
Instead of the for loop, I wanna use array (vectorization), then I did the following code:
a=b=np.arange(9).reshape(3,3)
c=np.zeros(3)
i=np.arange(3)
c[i]=np.average(b[np.where(a<i[:,None,None]+3)])
But it shows IndexError: too many indices for array
As for a<i[:,None,None]+3
it correctly shows
array([[[ True, True, True],
[False, False, False],
[False, False, False]],
[[ True, True, True],
[ True, False, False],
[False, False, False]],
[[ True, True, True],
[ True, True, False],
[False, False, False]]], dtype=bool)
But when I use b[np.where(a<i[:,None,None]+3)], it again shows IndexError: too many indices for array. I cannot get the correct output of c.
I am sensing you are trying to vectorize things here, though not explicitly mentioned. Now, I don't think you can index like that in a vectorized manner. To solve your qustion in a vectorized manner, I would suggest a more efficient way to get the sum-reduction with matrix-multiplication using np.tensordot and with help from broadcasting as you had set out already in your trials.
Thus, one solution would be -
from __future__ import division
i = np.arange(3)
mask = a<i[:,None,None]+3
c = np.tensordot(b,mask,axes=((0,1),(1,2)))/mask.sum((1,2))
Related post to understand tensordot.
Possible improvements on performance
Convert the mask to float dtype before feeding to np.dot as BLAS based matrix-multiplication would be faster with it.
Use np.count_nonzero instead of np.sum for counting booleans. So, use it to replace mask.sum() part.

How do I search for indices that satisfy condition in numpy?

I have columns corresponding to a given day, month, and year in a numpy array called 'a' and I am comparing all three of these values to the columns of another array called 'b' which also correspond to day,month, and year to find the index of 'a' that is equal to 'b' so far I have tried:
a[:,3:6,1] == b[1,3:6]
array([[False, True, True],
[ True, True, True],
[False, True, True],
...,
[False, False, False],
[False, False, False],
[False, False, False]], dtype=bool)
which works fine but I need the row that corresponds to [True,True,True]
I've also tried:
np.where(a[:,3:6,1] == b[1,3:6], a[:,3:6,1])
ValueError: either both or neither of x and y should be given
and
a[:,:,1].all(a[:,3:6,1] == b[1,3:6])
TypeError: only length-1 arrays can be converted to Python scalars
What is a quick and easy way to do this?
You can use np.all() along the last axis:
rows = np.where((a[:,3:6,1]==b[1,3:6]).all(axis=1))[0]
it will store in rows the indices where all the row contains True values.

Categories