numpy.diagonal

numpy.diagonal(a, offset=0, axis1=0, axis2=1)

Функция diagonal() возвращает указанные диагонали массива.

Для двумерных массивов возвращается диагональ с элементами индексы которых заданы выражением [i, i + offset], если offset = 0, то это будут элементы главной диагонали.

Для многомерных массивов возвращаются диагонали задаваемые параметрами axis1 и axis2 в виде двумерного массива, т.е. axis1 и axis2 задают плоскость вдоль которой извлекаются двумерные подмассивы исходного массива, а из тех, в свою очередь, и извлекаются диагонали.

Учитывая, что плоскость вдоль которой извлекаются подмассивы может так же содержать вложенные подмассивы, то вообще возвращаемы массив вовсе и не обязан быть двумерным. Он может быть абсолютно любой размерности, но все его элементы будут диагональными в плоскостях axis1 и axis2.

Параметры:
a - массив NumPy или подобный массиву объект.
Массив из которого извлекаются диагонали.
offset - целое число (необязательный параметр).
Задает смещение извлекаемой диагоналей (диагонали для двумерного массива).
axis1 - целое положительное число (необязательный параметр).
Ось которая будет первой осью в извлекаемых двумерных массивах, по умолчанию равна 0.
axis2 - целое положительное число (необязательный параметр).
Ось которая будет второй осью в извлекаемых двумерных массивах, по умолчанию равна 1.
Возвращает:
ndarray - массив NumPy
одномерный массив с диагональю двумерного исходного массива или многомерный массив с диагоналями подмассивов a извлеченных в плоскости двух его осей заданных параметрами axis1 и axis2.
Смотрите так же:
choose, take, select, diagonal, diag

Замечание

Данная функция так же реализована в виде метода базового класса ndarray.diagonal() с аналогичной сигнатурой (ndarray.diagonal(offset=0, axis1=0, axis2=1)) и принципом работы.

Имейте ввиду, что данная функция возвращает представление массива реализованное только для чтения, т.е. изменить элементы возвращаемого результата не получится. Однако, если значения все же необходимо изменять, то нужно переустановить флаг записи возвращаемого массива ndarray.setflags(write = True).




Примеры

Для двумерного массива возвращается без указания дополнительных параметров возвращается главная диагональ:

>>> import numpy as np
>>> 
>>> a = np.arange(30).reshape(5, 6)
>>> 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]])
>>> 
>>> np.diagonal(a)
array([ 0,  7, 14, 21, 28])

Параметр offsrt задает смещение диагонали:

>>> np.diagonal(a, offset = 1)
array([ 1,  8, 15, 22, 29])

Для массивов с большей размерностью все устроено несколько иначе - возвращается не одна диагональ, а диагонали каждого двумерного подмассива, плоскость которого задается параметрами axis1 и axis2:

>>> a = np.arange(27).reshape(3, 3, 3)
>>> 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]]])
>>> 
>>> np.diagonal(a, axis1 = 0, axis2 = 1)    #  axis1 = 0 и axis2 = 1 по умолчанию
array([[ 0, 12, 24],
       [ 1, 13, 25],
       [ 2, 14, 26]])

Параметры axis1 и axis2 позволяют переопределить оси массива вдоль которых извлекаются двумерные подмассивы:

>>> np.diagonal(a, axis1 = 0, axis2 = 2)
array([[ 0, 10, 20],
       [ 3, 13, 23],
       [ 6, 16, 26]])
>>> 
>>> np.diagonal(a, axis1 = 1, axis2 = 2)
array([[ 0,  4,  8],
       [ 9, 13, 17],
       [18, 22, 26]])

Параметр offset задаст смещение каждой из этих диагоналей.

>>> np.diagonal(a, offset = 1, axis1 = 1, axis2 = 2)
array([[ 1,  5],
       [10, 14],
       [19, 23]])

Данная функция может быть вызвана как метод:

>>> a.diagonal(offset = 1, axis1 = 1, axis2 = 2)
array([[ 1,  5],
       [10, 14],
       [19, 23]])

Довольно часто значения в возвращаемом массиве необходимо менять, но попытка сделать это приводит к ошибке:

>>> b = np.diagonal(a, offset = 1, axis1 = 1, axis2 = 2)
>>> b[0, 0]
1
>>> 
>>> b[0, 0] = 77
Traceback (most recent call last):
  File "", line 1, in 
ValueError: assignment destination is read-only

Что бы произвести присваивание достаточно изменить флаг записи массива b, но учитывая то, что возвращаемый массив является представлением исходного массива (ссылается на теже самые данные), то изменения повлекут за собой изменения в исходном массиве:

>>> b.setflags(write = True)
>>> 
>>> b[0, 0] = 77
>>> b
array([[77,  5],
       [10, 14],
       [19, 23]])
>>> 
>>> a
array([[[ 0, 77,  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]]])

Что бы данные в исходном массиве не изменялись достаточно выполнить полное копирование данных:

>>> b = np.diagonal(a, offset = 1, axis1 = 1, axis2 = 2).copy()
>>> b[0, 0] = 1
>>> b
array([[ 1,  5],
       [10, 14],
       [19, 23]])
>>> 
>>> a
array([[[ 0, 77,  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]]])

Если осей больше 3, то возвращаемый массив будет содержать вложенные подмассивы, но все они будут расположены по диагонали в плоскости axis1 и axis2:

>>> c = np.arange(32).reshape(2, 2, 2, 2, 2)
>>> c
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]]]]])
>>> 
>>> np.diagonal(c, axis1 = 1, axis2 = 4)
array([[[[ 0,  9],
         [ 2, 11]],

        [[ 4, 13],
         [ 6, 15]]],


       [[[16, 25],
         [18, 27]],

        [[20, 29],
         [22, 31]]]])