Generate three non-overlapping mask for 2-D matrix that covers all of it

Generate three non-overlapping mask for 2-D matrix that covers all of it



I have a 2-d array and I want to divide it into 3 non-overlapping and random sub-matrix by mask generation. For example I have a matrix like follow:


input = [[1,2,3],
[4,5,6],
[7,8,9]]



I want three random zero-one masks like follow:


mask1 = [[0,1,0],
[1,0,1],
[0,0,0]]
mask2 = [[1,0,0],
[0,1,0],
[1,0,0]]
mask3 =[[0,0,1],
[0,0,0],
[0,1,1]]



But my input matrix is too large and I need to do it in a fast way. I also want to determine the ratio of ones for every mask as input. In the above example the ratio is equal for all masks.
To produce one random mask, I use following code:


np.random.choice([0, 1],size=(size of matrix[0],size of matrix[1]))



My problem is how to produce non-overlapping masks.






So what is your question?

– Bartłomiej
Sep 16 '18 at 17:28






Submatrix or subarrays? Because if you mask like this you will get a 1-D array.

– Alex
Sep 16 '18 at 17:35






@Bartłomiej My problem is how to produce non-overlapping masks.

– user137927
Sep 16 '18 at 17:53






@Alex I need to produce a matrix or array with the same size as input (so-2d array) which contains one and zero.

– user137927
Sep 16 '18 at 17:54






I'm confused - posting a Minimal, Complete, and Verifiable example will help you get your question answered. In your case that involves making a sample matrix and an example of the output you are looking for.

– Alex
Sep 16 '18 at 17:56





1 Answer
1



IIUC, you can make a random matrix of 0, 1, and 2, and then extract the m == 0, m == 1, and m == 2 values:


groups = np.random.randint(0, 3, (5,5))
masks = (groups[...,None] == np.arange(3)[None,:]).T



However, this wouldn't guarantee an equal number of elements in each mask. To achieve that, you could permute a balanced allocation:


a = np.arange(25).reshape(5,5) # dummy input
groups = np.random.permutation(np.arange(a.size) % 3).reshape(a.shape)
masks = (groups[...,None] == np.arange(3)[None,:]).T



If you wanted a random probability to be in a group:


groups = np.random.choice([0,1,2], p=[0.3, 0.6, 0.1], size=a.shape)



or something. All you need to do is decide how you want to assign cells to groups, and then you can build your masks.


groups



For example:


In [431]: groups = np.random.permutation(np.arange(a.size) % 3).reshape(a.shape)

In [432]: groups
Out[432]:
array([[1, 0, 0, 2, 0],
[1, 2, 0, 0, 1],
[2, 0, 2, 0, 2],
[1, 1, 2, 1, 0],
[2, 2, 1, 1, 0]], dtype=int32)

In [433]: masks = (groups[...,None] == np.arange(3)[None,:]).T

In [434]: masks
Out[434]:
array([[[False, False, False, False, False],
[ True, False, True, False, False],
[ True, True, False, False, False],
[False, True, True, False, False],
[ True, False, False, True, True]],

[[ True, True, False, True, False],
[False, False, False, True, False],
[False, False, False, False, True],
[False, False, False, True, True],
[False, True, False, False, False]],

[[False, False, True, False, True],
[False, True, False, False, True],
[False, False, True, True, False],
[ True, False, False, False, False],
[False, False, True, False, False]]])



which gives me a full mask:


In [450]: masks.sum(axis=0)
Out[450]:
array([[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1],
[1, 1, 1, 1, 1]])



and reasonably balanced. If the number of cells were a multiple of 3, these numbers would all agree.


In [451]: masks.sum(2).sum(1)
Out[451]: array([9, 8, 8])



You can use .astype(int) to convert from a bool array to an int array of 0s and 1s if you like.


.astype(int)






Your idea is great, I am so so sorry that I forgot to note that I need to determine the ratio of ones in every mask.

– user137927
Sep 16 '18 at 18:11






I found out that there is problem when you compare groups and create masks. It only works when the number of rows and columns are equal.

– user137927
Sep 20 '18 at 14:56






@user137927: ah, that's easily changed. Have to finish an errand first and then I'll update. :-)

– DSM
Sep 20 '18 at 15:03






Oh yeah, I found the solution, just said to inform and make the answer flawless, thanks :)

– user137927
Sep 20 '18 at 19:57



Thanks for contributing an answer to Stack Overflow!



But avoid



To learn more, see our tips on writing great answers.



Required, but never shown



Required, but never shown




By clicking "Post Your Answer", you agree to our terms of service, privacy policy and cookie policy

Popular posts from this blog

𛂒𛀶,𛀽𛀑𛂀𛃧𛂓𛀙𛃆𛃑𛃷𛂟𛁡𛀢𛀟𛁤𛂽𛁕𛁪𛂟𛂯,𛁞𛂧𛀴𛁄𛁠𛁼𛂿𛀤 𛂘,𛁺𛂾𛃭𛃭𛃵𛀺,𛂣𛃍𛂖𛃶 𛀸𛃀𛂖𛁶𛁏𛁚 𛂢𛂞 𛁰𛂆𛀔,𛁸𛀽𛁓𛃋𛂇𛃧𛀧𛃣𛂐𛃇,𛂂𛃻𛃲𛁬𛃞𛀧𛃃𛀅 𛂭𛁠𛁡𛃇𛀷𛃓𛁥,𛁙𛁘𛁞𛃸𛁸𛃣𛁜,𛂛,𛃿,𛁯𛂘𛂌𛃛𛁱𛃌𛂈𛂇 𛁊𛃲,𛀕𛃴𛀜 𛀶𛂆𛀶𛃟𛂉𛀣,𛂐𛁞𛁾 𛁷𛂑𛁳𛂯𛀬𛃅,𛃶𛁼

Edmonton

Crossroads (UK TV series)