Numpy: Overlay Boolean Array on "True"s of other boolean array - arrays

I have a bool 2D-array A with the numbers of True being the dimension of bool 2D-array B.
A = np.array([[False, True, True, False, True],[False, False, False, False, False],[False, True, True, False, True]])
B = np.array([[True, False, True],[True, True, True]])
A =[[False, True, True, False, True],
[False, False, False, False, False],
[False, True, True, False, True]]
B =[[True, False, True],
[True, False, True]]
I want to "overlay" B on the "True"-Array of A, so that I'd get
C =
[[False, **True**, **False**, False, **True**],
[False, False, False, False, False],
[False, **True**, **False**, False, **True**]]
My ultimate goal is to manipulate an array
arr = [[1, 2, 3, 4, 5], [6,7,8,9,10], [11, 12,
13, 14, 15]]
with something like
arr[A] = arr[A] + B*2
to get
arr = [[1, 4, 3, 4, 7], [6,7,8,9,10], [11, 14,
13, 14, 17]]
Thanks in advance.

# get the indexes that are True
Xi = np.nonzero(A)
# convert to an array of 1D
B1 = np.ndarray.flatten(B)
# use Xi for dynamic indexing
A[Xi]=B1

The solution I came up with was (works only if B is quadratic):
arr[A] = (arr[A].reshape(len(B), len(B)) + 2 * B).ravel()

Related

How to generate all permutations of 1 and 0 bits of a given size in Swift

I would like to be able to generate an array of all possible permutations of a Bool (true/false or 1/0) of a given size n, in Swift. For example, given n=2 the result of calling generate(2) would be
let array: [Bool] = generate(2) // [[false, false], [false, true], [true, false], [true, true]]
I looked in Swift-algorithms but all I see is permutations and combinations of a provided array of elements. These algorithms don't appear to address scenario for a Bool with n>2. Also, I'm not sure what name to call this algorithm.
Here's a simple recursive implementation:
import Foundation
func recursion(depth: Int, arr: [[Bool]]) -> [[Bool]] {
if depth == .zero {
return arr
}
var newArr: [[Bool]] = []
for item in arr {
let newItem1 = item + [false]
let newItem2 = item + [true]
newArr += [newItem1, newItem2]
}
return recursion(depth: depth-1, arr: newArr)
}
print(recursion(depth: 1, arr: [[]]))
print(recursion(depth: 2, arr: [[]]))
print(recursion(depth: 3, arr: [[]]))
This gives the output:
[[false], [true]]
[[false, false], [false, true], [true, false], [true, true]]
[[false, false, false], [false, false, true], [false, true, false], [false, true, true], [true, false, false], [true, false, true], [true, true, false], [true, true, true]]
Just for fun a functional approach:
extension RangeReplaceableCollection {
var combinations: [Self] { generate(2) }
func generate(_ n: Int) -> [Self] {
repeatElement(self, count: n).reduce([.init()]) { result, element in
result.flatMap { elements in
element.map { elements + CollectionOfOne($0) }
}
}
}
}
Usage:
let elements = [false, true] // [false, true]
let combinations = elements.combinations // [[false, false], [false, true], [true, false], [true, true]]
let generateThree = elements.generate(3) // [[false, false, false], [false, false, true], [false, true, false], [false, true, true], [true, false, false], [true, false, true], [true, true, false], [true, true, true]]
or
let elements = [0, 1] // [0, 1]
let combinations = elements.combinations // [[0, 0], [0, 1], [1, 0], [1, 1]]
let generateThree = elements.generate(3) // [0, 0, 0], [0, 0, 1], [0, 1, 0], [0, 1, 1], [1, 0, 0], [1, 0, 1], [1, 1, 0], [1, 1, 1]]
or with Strings (Collection Of Characters):
let elements = "01" // "01"
let combinations = elements.combinations // ["00", "01", "10", "11"]
let generateThree = elements.generate(3) // ["000", "001", "010", "011", "100", "101", "110", "111"]

creating a new array from a big array using a small array to select values numpy

I have two numpy arrays - a big 6000x4 array and small 10x1 array.
big_array = array[[1,0.2,0.3,0.4],
[1,10.0,20.0,30.0],
[2,7.0,0.4,0.8]
[2,3,4,5]
...
[150,56,57,89]
[150,78,27,64]]
small_array = array([17, 12, 5, 12, 18, 11, 1, 4, 3, 9])
I want to create a new array using the values in the small array to select values from the big array. I can achieve this by using inputting single values in the following line:
new_array_0 = big_array[big_array[:,0]] == small_array[0]
new_array_1 = big_array[big_array[:,0]] == small_array[1]
I tried running this in a for loop:
subSet = np.empty((0,4))
for i in small_array:
a = big_array[big_array[:,0]] == small_array[i]
subSet = np.append(subSet,a,axis=0)
But this results in an error.
Is there a python/numpy way to achieve this?
I took a small sample from your post:
>>> big_array = np.array([[ 1, 0, 0, 0],
[ 1, 10, 20, 30],
[ 2, 7, 0, 0],
[ 2, 3, 4, 5],
[ 2, 56, 57, 89],
[ 1, 78, 27, 64]])
>>> small_array = torch.array([20, 10, 30])
The way I see it, you have a two dimensional array big_array[big_array[:,0]] which you want to compare to scalar values contained in small_array. Comparing an array with a single scalar will return an array of same shape where the conditional will have been called element-wise, leaving you with a boolean mask:
>>> big_array[big_array[:,0]] == small_array[0]
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]])
Of course, if you compare to small_array straight away, it will check array-to-array, which will return False and perharps even a DeprecationWarning warning:
>>> big_array[big_array[:,0]] == small_array
False
What you could do though, is broadcast your small_array:
>>> small_array[:, None, None].shape
(10, 1, 1)
This way you can compare the indexed array with your small_array's scalar values:
>>> big_array[big_array[:,0]] == small_array[:, None, None]
array([[[False, False, True, False],
[False, False, True, False],
[False, False, False, False],
[False, False, False, False],
[False, False, False, False],
[False, False, True, False]],
[[False, True, False, False],
[False, True, False, False],
[False, False, False, False],
[False, False, False, False],
[False, False, False, False],
[False, True, False, False]],
[[False, False, False, True],
[False, False, False, True],
[False, False, False, False],
[False, False, False, False],
[False, False, False, False],
[False, False, False, True]]])
Which is the same result as the one yielded by big_array[big_array[:,0]] == small_array[0], big_array[big_array[:,0]] == small_array[1], and big_array[big_array[:,0]] == small_array[2].

numpy logical.xor on a 2D array

I have a 2D numpy array with only 0 and 255 values (created from a black and white image) that i'd like to XOR with another similar 2D array.
The dtype of these arrays is uint8 and their shapes are identical.
The only information and examples i've been able to find, so far, deal with 1D arrays.
Do I need to 'flatten' these 2D arrays before XOR'ing? If so, how is that done?
numpy.logical_xor and numpy.bitwise_xor will work for 2-D arrays, as will the operators != and ^ (essentially logical and bitwise XOR, respectively).
edit: I just noticed in your title you are looking for logical XOR, but I will leave the bitwise info there for reference in case it's helpful.
Setup:
a = np.random.choice([0,255], (5,5))
b = np.random.choice([0,255], (5,5))
>>> a
array([[255, 255, 0, 255, 255],
[255, 255, 0, 255, 0],
[255, 0, 0, 0, 0],
[ 0, 255, 255, 255, 255],
[ 0, 0, 255, 0, 0]])
>>> b
array([[ 0, 255, 255, 255, 255],
[255, 0, 0, 255, 0],
[255, 0, 255, 0, 255],
[ 0, 0, 0, 0, 0],
[255, 0, 0, 0, 255]])
Logical XOR:
>>> np.logical_xor(a,b)
array([[ True, False, True, False, False],
[False, True, False, False, False],
[False, False, True, False, True],
[False, True, True, True, True],
[ True, False, True, False, True]])
# equivalently:
>>> a!=b
array([[ True, False, True, False, False],
[False, True, False, False, False],
[False, False, True, False, True],
[False, True, True, True, True],
[ True, False, True, False, True]])
Bitwise XOR:
>>> np.bitwise_xor(a,b)
array([[255, 0, 255, 0, 0],
[ 0, 255, 0, 0, 0],
[ 0, 0, 255, 0, 255],
[ 0, 255, 255, 255, 255],
[255, 0, 255, 0, 255]])
# equivalently:
>>> a^b
array([[255, 0, 255, 0, 0],
[ 0, 255, 0, 0, 0],
[ 0, 0, 255, 0, 255],
[ 0, 255, 255, 255, 255],
[255, 0, 255, 0, 255]])

Convert Boolean Value with true into an array in Angular4 (Typescript)

I am getting a set of boolean values from my microservice.
"mon": true,
"tues": false,
"wed": false,
"thurs": true,
"fri": false,
"sat": true,
"sun": false,
And I need to convert the values with boolean value true to an array like
following:
options = ['mon', 'thurs', 'sat']
How can I do it?
You need to use filter on the object keys for those days key:
var day = {
"mon": true,
"tues": false,
"wed": false,
"thurs": true,
"fri": false,
"sat": true,
"sun": false
};
var res = Object.keys(day).filter(key => day[key]);
console.log(res);
You can filter the keys:
const obj = {
"mon": true,
"tues": false,
"wed": false,
"thurs": true,
"fri": false,
"sat": true,
"sun": false,
};
const options = Object.keys(obj).filter(key => obj[key]);
console.log(options);
Just another way with entries and array destructure 🚀🚀
let day = {
"mon": true,
"tues": false,
"wed": false,
"thurs": true,
"fri": false,
"sat": true,
"sun": false
};
let result = Object.entries(day).filter(([key, state]) =>state).map(([key]) => key);
console.log(result);

Create mask by first positions only

I have array:
a = np.array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4],
[ 1, 2, 5, 4, 0, 4]])
I need select only from first consecutive 0 in each row:
[[ True False False False False False]
[ True False False False False False]
[ True True False False False False]
[ False False False False False False]]
I try:
a[np.arange(len(a)), a.argmax(1): np.arange(len(a)), [0,0,0]] = True
But this is wrong.
You can use np.cumsum.
Assumption: you are looking for zeros only at the start of each row.
a = np.array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4]])
a.cumsum(axis=1) == 0
array([[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, True, False, False, False, False]], dtype=bool)
Basis: holds True for as long as the cumulative sum is 0 along each row.
Error-prone: an array with negative ints would cause this to fail. I.e. for [-1, 1], this would evaluate to True at position 1.
You might use np.minimum.accumulate with the condition testing a == 0(over the rows); Since non zero gives False, so elements come after the first non zero will be set to False due to the accumulated minimum:
np.minimum.accumulate(a == 0, axis=1)
#array([[ True, False, False, False, False, False],
# [ True, False, False, False, False, False],
# [ True, True, False, False, False, False],
# [False, False, False, False, False, False]], dtype=bool)
Here's one with argmin + broadcasting -
(a==0).argmin(1)[:,None] > np.arange(a.shape[1])
Explanation with a sample step-by-step run
1) Input array :
In [207]: a
Out[207]:
array([[ 0, 1, 2, 0, 0, 0],
[ 0, 4, 1, 35, 0, 10],
[ 0, 0, 5, 4, 0, 4],
[ 1, 2, 5, 4, 0, 4]])
2) Mask of zeros
In [208]: (a==0)
Out[208]:
array([[ True, False, False, True, True, True],
[ True, False, False, False, True, False],
[ True, True, False, False, True, False],
[False, False, False, False, True, False]], dtype=bool)
3) Get the indices where the False occurs signalling the end of first True island for each row. Thus, for any row where there is no zero or if the first element is non-zero would result in argmin output as 0. Thus, our next task would be to use broadcasting to create a mask that starts as True from first row and stops being True at those argmin indices. This would be one with broadcasted-comparison against a range array extending covering all columns.
In [209]: (a==0).argmin(1)
Out[209]: array([1, 1, 2, 0])
In [210]: (a==0).argmin(1)[:,None] > np.arange(a.shape[1])
Out[210]:
array([[ True, False, False, False, False, False],
[ True, False, False, False, False, False],
[ True, True, False, False, False, False],
[False, False, False, False, False, False]], dtype=bool)
Timings
In [196]: a = np.random.randint(0,9,(5000,5000))
In [197]: %timeit a.cumsum(axis=1) == 0 ##Brad Solomon
...: %timeit np.minimum.accumulate(a == 0, axis=1) ##Psidom
...: %timeit (a==0).argmin(1)[:,None] > np.arange(a.shape[1])
...:
10 loops, best of 3: 69 ms per loop
10 loops, best of 3: 64.9 ms per loop
10 loops, best of 3: 32.8 ms per loop

Resources