I’m looking for an efficient way to make index matrix to Boolean matrix, without a loop (with NumPy).
The index matrix build from tuples which represents indices. I need to build a Boolean matrix (in different and known size) from it, which going to “1” on all of the indices that in the index matrix, and “0” in all the other positions. As an example if x
array with shape (5, 3, 2) be as:
x = np.array([[[0, 0], [0, 1], [0, 3]],
[[1, 0], [1, 3], [1, 4]],
[[2, 2], [2, 3], [2, 4]],
[[3, 1], [3, 3], [3, 4]],
[[4, 2], [4, 3], [4, 4]]])
the desired output be in shape (5, 5) as:
[[1 1 0 1 0]
[1 0 0 1 1]
[0 0 1 1 1]
[0 1 0 1 1]
[0 0 1 1 1]]
- In the first line the indices given are
(0,0) (0,1) (0,3)
, so the first line of the Boolean matrix is 11010 (1 where index exists and 0 otherwise) - In the next line the indices are
(1,0) (1,3) (1,4)
, so the line in the Boolean matrix is 10011
And so on…
I wrote a function that do it with loops, it’s attached. But it performs too slow! I’m looking for much efficiency way, with NumPy.
Thanks for all helpers!!
CodePudding user response:
Row and column ids arrays can be taken from x
using indexing. Then we can create a zero NumPy array with the desired shape; where, maximum column numbers can be taken from the x
values and row numbers will be as for x
:
row_ids = x[:, :, 0]
# [[0 0 0]
# [1 1 1]
# [2 2 2]
# [3 3 3]
# [4 4 4]]
cols_ids = x[:, :, 1]
# [[0 1 3]
# [0 3 4]
# [2 3 4]
# [1 3 4]
# [2 3 4]]
B = np.zeros((x.shape[0], x.max() 1), dtype=np.int64)
# [[0 0 0 0 0]
# [0 0 0 0 0]
# [0 0 0 0 0]
# [0 0 0 0 0]
# [0 0 0 0 0]]
Now, we can fill the B
array by 1
using indexing as:
B[row_ids, cols_ids] = 1
# [[1 1 0 1 0]
# [1 0 0 1 1]
# [0 0 1 1 1]
# [0 1 0 1 1]
# [0 0 1 1 1]]