Есть несколько способов сделать это. Самым простым, конечно же, является работа с матрицами.
Но вы также можете векторизовать операции над raveled-массивом. Например, скажем, у вас была ладья на позиции 0 <= n < 64
в линейном массиве. Чтобы установить строку равной единице, используйте целочисленное деление:
array[8 * (n // 8):8 * (n // 8 + 1)] = True
Чтобы установить столбец, используйте по модулю:
array[n % 8::8] = True
Вы можете преобразовать в матрицу, используя reshape
:
matrix = array.reshape(8, 8)
И обратно, используя ravel
:
array = martix.ravel()
Или reshape
:
array = matrix.reshape(-1)
Установка единиц в матрице еще проще, учитывая специфику c строка 0 <= m < 8
и столбец 0 <= n < 8
:
matrix[m, :] = matrix[:, n] = True
Теперь единственный вопрос - как векторизовать несколько индексов одновременно. Как это бывает, вы можете использовать причудливый индекс на одной оси. Т.е. приведенное выше выражение можно использовать с m
и n
, содержащими несколько элементов:
m, n = np.nonzero(matrix)
matrix[m, :] = matrix[:, n] = True
Вы даже можете играть в игры и делать это с массивом, также используя причудливую индексацию:
n = np.nonzero(array)[0]
r = np.linspace(8 * (n // 8), 8 * (n // 8 + 1), 8, False).T.ravel()
c = np.linspace(n % 8, n % 8 + 64, 8, False)
array[r] = array[c] = True
Использование linspace
позволяет одновременно генерировать несколько последовательностей одного размера. Каждая последовательность представляет собой столбец, поэтому мы транспонируем перед перемещением, хотя это и не требуется.