Создайте три неперекрывающиеся маски для двумерной матрицы, которая покрывает все это - PullRequest
0 голосов
/ 16 сентября 2018

У меня есть двумерный массив, и я хочу разделить его на 3 непересекающиеся и случайные субматрицы путем генерации маски.Например, у меня есть следующая матрица:

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

Мне нужны три случайные маски нулевой единицы, такие как 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]]

Но моя входная матрица слишком велика, и мне нужно сделатьэто по-быстрому.Я также хочу определить соотношение единиц для каждой маски в качестве входных данных.В приведенном выше примере соотношение одинаково для всех масок.Чтобы создать одну случайную маску, я использую следующий код:

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

Моя проблема в том, как создать неперекрывающиеся маски.

1 Ответ

0 голосов
/ 16 сентября 2018

IIUC, вы можете создать случайную матрицу из 0, 1 и 2, а затем извлечь значения m == 0, m == 1 и m == 2:

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

Однакоэто не гарантирует равное количество элементов в каждой маске.Чтобы достичь этого, вы можете изменить сбалансированное распределение:

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

Если вы хотите, чтобы случайная вероятность была в группе:

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

или что-то еще.Все, что вам нужно сделать, это решить, как вы хотите назначить ячейки для groups, а затем вы можете создать свои маски.

Например:

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]]])

, что дает мне полную маску:

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]])

и достаточно сбалансирован.Если бы число ячеек было кратно 3, все эти числа были бы согласны.

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

Вы можете использовать .astype(int) для преобразования из массива bool в массив int из 0 и 1, если хотите.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...