Как минимум одно значение True на столбец в логическом массиве numpy - PullRequest
0 голосов
/ 28 февраля 2020

Предположим, у меня есть очень большой двумерный логический массив (для примера возьмем размеры 4 строки x 3 столбца):

toto = np.array([[True, True, False],
                [False, True, False],
                [True, False, False],
                [False, True, False]])

Я хочу преобразовать toto, чтобы он содержал по крайней мере одно значение True на столбец, оставляя другие столбцы нетронутыми.

РЕДАКТИРОВАТЬ: Правило таково: если все столбцы ложные, я хочу ввести True в случайную строку.

Так что в этом примере один из Ложных в 3-м столбце должен стать Истиной.

Как бы вы сделали это эффективно?

Заранее спасибо

Ответы [ 2 ]

1 голос
/ 29 февраля 2020
import numpy as np

toto = np.array([[False, True, False], [False, True, False],
                 [False, False, False], [False, True, False]])

# First we get a boolean array indicating columns that have at least one True value
mask = np.any(toto, axis=0)

# Now we invert the mask to get columns indexes (as boolean array) with no True value
mask = np.logical_not(mask)

# Notice that if we index with this mask on the colum dimension we get elements
# in all rows only in the columns containing no True value. The dimension is is
# "num_rows x num_columns_without_true"
toto[:, mask]

# Now we need random indexes for rows in the columns containing only false. That
# means an array of integers from zero to `num_rows - 1` with
# `num_columns_without_true` elements
row_indexes = np.random.randint(toto.shape[0], size=np.sum(mask))

# Now we can use both masks to select one False element in each column containing only False elements and set them to True
toto[row_indexes, mask] = True

Отказ от ответственности: mathfux был быстрее с тем же решением, которое я писал (примите его ответ, если это то, что вы искали), но так как я писал с большим количеством комментариев, я решил в любом случае.

1 голос
/ 28 февраля 2020

Вы можете сделать это следующим образом:

col_mask = ~np.any(toto, axis=0)
row_idx = np.random.randint(toto.shape[0], size=np.sum(col_mask))
toto[row_idx, col_mask]=True

col_mask - это array([False, False, True]) изменяемых столбцов. row_idx - массив, состоящий из изменяемых индексов строк.

...