2015-05-05 8 views
2

У меня есть многомерная матрица с размерами (7, 3, 7, 3), и я хотел бы изменить обобщенную диагональ, в которой ось 0 и ось 2 совпадают. Эта обобщенная диагональ будет определяться как те элементы массива, чей 0-й и 2-й индексы совпадают и будут иметь форму (3, 3, 7).Изменение диагоналей в многомерных массивах numpy

Выполнение:

arr.diagonal(axis1=0, axis2=2) 

я могу получить доступ к элементам диагонали, но я не могу изменить их «на месте», по крайней мере, в версии 1.8.2 NumPy.

Numpy documentation объясняет, что с версией 1.10 это возможно. Однако, поскольку я полагаюсь на других людей, использующих один и тот же код, обновление до numpy 1.10 не является вариантом. Документация также предлагает использовать .copy(), чтобы иметь портативное решение, но .copy() создаст копию массива, но это не поможет, если я хочу изменить диагонали исходного массива.

В качестве альтернативы я попытался индексировать диагональные элементы непосредственно [с помощью ввода, взятого из numpy.indices ((7, 3, 7, 3))], но без успеха.

Как я могу получить доступ к элементам обобщенной диагонали, чтобы изменить исходный массив в numpy 1.8.2?

ответ

2

Одним из способов создания такого обобщенного диагонального представления является использование функции as_strided из модуля numpy.lib.stride_tricks. Шаг для оси, связанный с диагональю двух осей, является суммой шагов этих осей.

Например:

In [196]: from numpy.lib.stride_tricks import as_strided 

Создать массив с формой (7, 3, 7, 3):

In [197]: a = np.arange(21*21).reshape(7,3,7,3) 

In [198]: a[5, :, 5, :] 
Out[198]: 
array([[330, 331, 332], 
     [351, 352, 353], 
     [372, 373, 374]]) 

Создать вид "диагональ", связанный с осями 0 и 2 . вид имеет форму (3, 3, 7):

In [199]: d = as_strided(a, strides=(a.strides[1], a.strides[3], a.strides[0] + a.strides[2]), shape=(3, 3, 7)) 

Убедитесь, что, например, d[:, :, 5] является такой же, как a[5, :, 5, :]:

In [200]: d[:, :, 5] 
Out[200]: 
array([[330, 331, 332], 
     [351, 352, 353], 
     [372, 373, 374]]) 

Убедитесь, что d является видом a путем модификации d и видя, что a изменилось:

In [201]: d[1, 1, 5] = -1 

In [202]: a[5, :, 5, :] 
Out[202]: 
array([[330, 331, 332], 
     [351, -1, 353], 
     [372, 373, 374]]) 

Будьте осторожны с as_strided! Если вы ошиблись в аргументах, вы можете записать их в память за пределами a, что может привести к сбою python.