Преобразование элементов массива в бинарные значения

Есть двумерный массив вида

a = numpy.array(
   [[0.0, 0.967, 0.994, 0.001, 0.001, 0.977, 0.0],
    [0.002, 0.947, 0.998, 0.0, 0.001, 0.013, 0.0],
    [0.004, 0.331, 0.968, 0.002, 0.002, 0.202, 0.001]]
)

Каждая колонка - отдельный класс, а значения в них - вероятности. Мне нужно привести к бинарному виду, т.е. получить

b = numpy.array(
      [[0, 1, 1, 0, 0, 1, 0],
       [0, 1, 1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0]]
)

Я бы мог это сделать так b = ( a > 0.5 ).astype(int), однако для каждого класса может быть своя вероятность, т.е. для первой колонки 0.7, для второй 0.5, для третьей 0.9 и тд.

Есть ли метод которым я бы мог применить такой фильтр или все же придется пробегать с помощью циклов по массиву и сравнивать значения??


Ответы (2 шт):

Автор решения: splash58

Если я вас правильно понял, то можно так

a = np.array(
   [[0.0, 0.967, 0.994, 0.001, 0.001, 0.977, 0.0],
    [0.002, 0.947, 0.998, 0.0, 0.001, 0.013, 0.0],
    [0.004, 0.331, 0.968, 0.002, 0.002, 0.202, 0.001]]
)

>>> b = np.array([0.5,.3,0.7]).reshape(3,1)
>>> b
array([[0.5],
       [0.3],
       [0.7]])

>>> ( a > b ).astype(int)
array([[0, 1, 1, 0, 0, 1, 0],
       [0, 1, 1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0]])
→ Ссылка
Автор решения: Илья Митусов

Альтерантивный вариант

a = np.array(
   [[0.0, 0.967, 0.994, 0.001, 0.001, 0.977, 0.0],
    [0.002, 0.947, 0.998, 0.0, 0.001, 0.013, 0.0],
    [0.004, 0.331, 0.968, 0.002, 0.002, 0.202, 0.001]]
)

mask = np.array([.7, .3, .9]).reshape(3, 1) #вероятности для классов
np.where(a < mask, 0, 1)

array([[0, 1, 1, 0, 0, 1, 0],
       [0, 1, 1, 0, 0, 0, 0],
       [0, 0, 1, 0, 0, 0, 0]])

Хотя решение, предложенное @splash58 существенно быстрее

a = np.random.rand(3, 100000)

%%timeit
b = np.array([0.5,.3,0.7]).reshape(3,1)
(a > b).astype(int)
155 µs ± 807 ns per loop (mean ± std. dev. of 7 runs, 10000 loops each)

%%timeit
mask = np.array([.7, .3, .9]).reshape(3, 1)
np.where(a < mask, 0, 1)
981 µs ± 9.09 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)
→ Ссылка