修改多维numpy数组中的对角线

时间:2021-01-23 21:38:21

I have a multidimensional numpy array of shape (7, 3, 7, 3) and I would like to modify the generalized diagonal in which axis 0 and axis 2 coincide. This generalized diagonal would be defined as those elements of the array whose 0th and 2nd index coincide, and would have shape (3, 3, 7).

我有一个多维的numpy数组形状(7,3,7,3),我想修改轴0和轴2重合的广义对角线。该广义对角线将被定义为第0和第2指数重合的阵列的那些元素,并且将具有形状(3,3,7)。

Doing:

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

I can access to the elements of the diagonal, but I cannot modify them 'in place', at least in version 1.8.2 of numpy.

我可以访问对角线的元素,但我不能“就地”修改它们,至少在numpy版本1.8.2中。

Numpy documentation explains that with version 1.10 this might be possible. However, since I depend on other people using the same code, updating to numpy 1.10 is not an option. Documentation also suggests using .copy() in order to have a portable solution, but .copy() will make a copy of the array, but this is of no help if I want to modify the diagonals of the original array.

Numpy文档解释说,对于版本1.10,这可能是可能的。但是,由于我依赖于使用相同代码的其他人,因此无法更新为numpy 1.10。文档还建议使用.copy()以获得可移植的解决方案,但.copy()将生成数组的副本,但如果我想修改原始数组的对角线,这没有任何帮助。

Alternatively, I have tried indexing the diagonal elements directly [with input taken from numpy.indices((7, 3, 7, 3))], but with no success.

或者,我尝试直接索引对角线元素[输入来自numpy.indices((7,3,7,3))],但没有成功。

How could I access the elements of the generalized diagonal to modify the original array in numpy 1.8.2?

如何在numpy 1.8.2中访问广义对角线的元素来修改原始数组?

1 个解决方案

#1


One way to create such a generalized diagonal view is to use the as_strided function from the module numpy.lib.stride_tricks. The stride for the axis associated with the diagonal of the two axes is the sum of the strides of those axes.

创建这种广义对角线视图的一种方法是使用模块numpy.lib.stride_tricks中的as_strided函数。与两个轴的对角线相关联的轴的步幅是这些轴的步幅的总和。

For example:

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

Create an array with shape (7, 3, 7, 3):

创建一个形状为(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]])

Create a view of the "diagonal" associated with axes 0 and 2. The view has shape (3, 3, 7):

创建与轴0和2关联的“对角线”视图。视图具有形状(3,7,7):

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

Check that, for example, d[:, :, 5] is the same as a[5, :, 5, :]:

例如,检查d [:,:,5]是否与[5,:,5,:]相同:

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

Verify that d is a view of a by modifying d and seeing that a has changed:

通过修改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]])

Be careful with as_strided! If you get the arguments wrong, you can write to memory outside of a, possibly causing python to crash.

小心as_strided!如果你的参数错误,你可以写入a之外的内存,可能导致python崩溃。

#1


One way to create such a generalized diagonal view is to use the as_strided function from the module numpy.lib.stride_tricks. The stride for the axis associated with the diagonal of the two axes is the sum of the strides of those axes.

创建这种广义对角线视图的一种方法是使用模块numpy.lib.stride_tricks中的as_strided函数。与两个轴的对角线相关联的轴的步幅是这些轴的步幅的总和。

For example:

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

Create an array with shape (7, 3, 7, 3):

创建一个形状为(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]])

Create a view of the "diagonal" associated with axes 0 and 2. The view has shape (3, 3, 7):

创建与轴0和2关联的“对角线”视图。视图具有形状(3,7,7):

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

Check that, for example, d[:, :, 5] is the same as a[5, :, 5, :]:

例如,检查d [:,:,5]是否与[5,:,5,:]相同:

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

Verify that d is a view of a by modifying d and seeing that a has changed:

通过修改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]])

Be careful with as_strided! If you get the arguments wrong, you can write to memory outside of a, possibly causing python to crash.

小心as_strided!如果你的参数错误,你可以写入a之外的内存,可能导致python崩溃。