Прежде всего, из вашего описания кажется, что элемент не может быть нулевым, поэтому давайте предположим, что (без потери общности).
Существует 2**n
возможных комбинаций знаков (3**n
, если мы разрешаем нули), где n
- количество столбцов. Их можно кодировать в векторе, который называется outcomes
ниже.
Далее я покажу, как мы можем применить матричное умножение для решения этой проблемы.
Пусть M
будет вашей входной матрицей:
In [36]: M
Out[36]:
array([[-0.5, 0.5, -1. ],
[ 1. , -0.5, -1. ],
[-1. , -1. , -0.5],
[ 0.5, 1. , -1. ],
[ 1. , 0.5, 1. ]])
In [37]: m, n = M.shape
Теперь мы:
- преобразовать
M
в двоичную матрицу, кодирующую знак каждого элемента;
- считывать каждую строку результата, как если бы это было число с основанием 2.
Это дает для каждой строки M
индекс соответствующего результата:
In [40]: outcome_index = np.matmul(M > 0, [2**i for i in range(n)])
In [41]: outcome_index
Out[41]: array([2, 1, 0, 3, 7])
Наконец, мы используем индекс для вычисления нового столбца:
In [42]: outcomes[outcome_index]
Out[42]: array([-1, -1, 1, 1, -1])
Добавление столбца к M
оставлено в качестве упражнения для читателя. :)
P.S. Я использовал следующий outcomes
вектор в этом примере:
In [43]: outcomes
Out[43]: array([ 1, -1, -1, 1, 1, -1, -1, -1])
P.P.S. Я только что заметил, что мой код считывает число base-2 справа налево вместо более естественного (для меня) слева направо. Это на самом деле не проблема, и ее легко изменить (также оставлено в качестве упражнения для читателя).