To swap the main (top-down left-right) and bottom-up left-right diagonals in the nxn matrix, there is an O(n) algorithm:
>>> import numpy as np >>> a = np.arange(49).reshape(7, -1) >>> a array([[ 0, 1, 2, 3, 4, 5, 6], [ 7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 30, 31, 32, 33, 34], [35, 36, 37, 38, 39, 40, 41], [42, 43, 44, 45, 46, 47, 48]]) >>> old_main_diagonal = a.diagonal().copy() >>> np.fill_diagonal(a, np.flipud(a).diagonal()) >>> np.fill_diagonal(np.flipud(a), old_main_diagonal) >>> a array([[42, 1, 2, 3, 4, 5, 48], [ 7, 36, 9, 10, 11, 40, 13], [14, 15, 30, 17, 32, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 16, 31, 18, 33, 34], [35, 8, 37, 38, 39, 12, 41], [ 0, 43, 44, 45, 46, 47, 6]])
It is worth noting that np.flipud(a).diagonal() is O(1) (in numpy 1.9+), since no copy occurs.
numpy.flipud(a) returns the view of array a upside down. a.diagonal() returns a view to the main diagonal. numpy.fill_diagonal(a, value) replaces in place the main diagonal in a with value .
To swap the main and diagonal "top-down right-left":
>>> a = np.arange(49).reshape(7, -1) >>> a array([[ 0, 1, 2, 3, 4, 5, 6], [ 7, 8, 9, 10, 11, 12, 13], [14, 15, 16, 17, 18, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 30, 31, 32, 33, 34], [35, 36, 37, 38, 39, 40, 41], [42, 43, 44, 45, 46, 47, 48]]) >>> old_main_diag_in_reverse = a.diagonal()[::-1].copy() >>> np.fill_diagonal(a, np.fliplr(a).diagonal()) >>> np.fill_diagonal(np.flipud(a), old_main_diag_in_reverse) >>> a array([[ 6, 1, 2, 3, 4, 5, 0], [ 7, 12, 9, 10, 11, 8, 13], [14, 15, 18, 17, 16, 19, 20], [21, 22, 23, 24, 25, 26, 27], [28, 29, 32, 31, 30, 33, 34], [35, 40, 37, 38, 39, 36, 41], [48, 43, 44, 45, 46, 47, 42]])