Объединение массивов Numpy 2d при гарантированном ненулевом равенстве

1

У меня есть два массива NxN numpy, они равного размера.

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

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

Я хотел бы объединить оба массива таким образом, что для каждой [строки, col], если один массив имеет значение 0, а другой имеет ненулевое значение, тогда мой второй массив будет изменен (если необходимо), чтобы иметь ненулевое значение,

И, если оба они имеют ненулевое значение (что гарантировано будет одинаковым значением), то для этой строки, колонки не будет изменений, она останется прежней.

Пример:

массив 1:

[[0,9],[2,0]]

массив 2:

[[0,0],[2,2]]

После выполнения моего "объединения" мне нужен массив 2:

[[0,9],[2,2]]

Что такое быстрый способ сделать это для больших матриц? Спасибо.

Теги:
arrays
numpy
matrix

2 ответа

2
Лучший ответ

Все, что вы хотите сделать, это изменить нули во втором массиве на элементы в одном индексе в первом массиве. Вы можете сделать следующее:

mask = arr2 == 0
arr2[mask] = arr1[mask]

Демо-версия:

In [7]: arr1 = np.array([[0,9],[2,0]])

In [8]: arr2 = np.array([[0,0],[2,2]])

In [9]: mask = arr2 == 0

In [10]: arr2[mask] = arr1[mask]

In [11]: arr2
Out[11]: 
array([[0, 9],
       [2, 2]])
  • 0
    так круто! Я не думал, что можно будет сделать это так элегантно.
  • 0
    @TravisBlack В этом волшебство векторизации и, конечно, некоторые абстракции.
1

Поскольку вы просите "быстро", вы можете быть заинтересованы в np.copyto:

>>> a = np.random.randint(0, 2, (100, 100))
>>> b = np.random.randint(-1, 1, (100, 100))
>>> 
>>> 
>>> timeit("bk = b.copy(); mask=bk==0; bk[mask] = a[mask]", globals=globals(), number=10000)
1.3142543959984323
>>> timeit("bp = b.copy(); np.copyto(bp, a, where=bp==0)", globals=globals(), number=10000)
0.7330851459992118
>>> 
# check results are the same
>>> bk = b.copy(); mask=bk==0; bk[mask] = a[mask]
>>> bp = b.copy(); np.copyto(bp, a, where=bp==0)
>>> np.all(bk==bp)
True

Ещё вопросы

Сообщество Overcoder
Наверх
Меню