Python 获取影响原始数组的2D numpy数组的对角线

Python 获取影响原始数组的2D numpy数组的对角线,python,arrays,numpy,Python,Arrays,Numpy,我有一个2D numpy数组。我想通过创建其对角线元素的数组并修改对角线数组来修改它,以便这些更改反映在原始2D数组上 我试过: >>> a = np.ones(shape=(3,3)) >>> d1 = a[np.diag_indices_from(a)] >>> d1 array([1., 1., 1.]) >>> d1[0] = 2 >>> d1 array([2., 1., 1.]) >>

我有一个2D numpy数组。我想通过创建其对角线元素的数组并修改对角线数组来修改它,以便这些更改反映在原始2D数组上

我试过:

>>> a = np.ones(shape=(3,3))
>>> d1 = a[np.diag_indices_from(a)]
>>> d1
array([1., 1., 1.])
>>> d1[0] = 2
>>> d1
array([2., 1., 1.])
>>>a
array([[1., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
可以看出,这些更改不会影响原始阵列

是否有任何方法可以创建也会影响原始二维阵列的对角线阵列

编辑: 当我处理行或列时,我得到了我想要的效果:

>>> row0 = a[0]
>>> row0[0] = 0
>>> a
array([[0., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
>>> column0=a[:,0]
>>> column0[2]=3
>>> a
array([[0., 1., 1.],
       [1., 1., 1.],
       [3., 1., 1.]])
当你像那样建立索引()时,你就是。您只需按照定义的方式将
d1
分配回
a

a=np.one(形状=(3,3))
d1=a[np.从(a)中得出的诊断指数]
d1[0]=2
a[np.从(a)中得出的诊断指数]=d1

恐怕不行。NumPy数组是一个类对象,具有自己的索引接口。当你创建一个对角线(一个向量)作为一个单独的对象时,你打破了原来的索引模式,用另一个替代它——向量是一个单独的对象

如果需要此功能,可以编写自己的类,为每个矩阵元素创建一个新的
元素
对象。然后,您可以随时更改这些元素(通过类方法),更改元素值,但保持元素实例不变


这样,无论何时提取对角线(或任何其他矩阵切片、引用等),都可以使用原始对象,而不是不变的值。

正确的方法是使用
np.diagonal
np.fill\u diagonal
。下面还添加了一种扭曲numpy的方法:

a = np.ones(shape=(3,3))
d1 = np.diagonal(a).copy()
d1[0] = 2
np.fill_diagonal(a,d1)
输出:

a

[[2. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
a

[[2. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
注意,基于:从NumPy 1.9开始,它返回原始数组的只读视图。尝试写入结果数组将产生错误。 在将来的某个版本中,它将返回一个读/写视图,写入返回的数组将改变原始数组。返回的数组将具有与输入数组相同的类型

为了扭转numpy,您可以这样做,但我建议使用上述解决方案:

a = np.ones(shape=(3,3))
d1 = np.diagonal(a)
d1.setflags(True)
d1[0] = 2
np.fill_diagonal(a,d1)
输出:

a

[[2. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]
a

[[2. 1. 1.]
 [1. 1. 1.]
 [1. 1. 1.]]

您可以使用
np.einsum
精确地获得您想要的:

。。versionadded::1.10.0

Views returned from einsum are now writeable whenever the input array
is writeable. For example, ``np.einsum('ijk...->kji...', a)`` will now
have the same effect as :py:func:`np.swapaxes(a, 0, 2) <numpy.swapaxes>`
and ``np.einsum('ii->i', a)`` will return a writeable view of the diagonal
of a 2D array.

使用阵列展开版本的基本索引,可以:

In [150]: a = np.ones((3,3))                                                                         
In [151]: d1 = a.ravel()[::4]                                                                        
In [152]: d1[0] *= 2                                                                                 
In [153]: a                                                                                          
Out[153]: 
array([[2., 1., 1.],
       [1., 1., 1.],
       [1., 1., 1.]])
In [154]: d1[:] = [1,2,3]                                                                            
In [155]: a                                                                                          
Out[155]: 
array([[1., 1., 1.],
       [1., 2., 1.],
       [1., 1., 3.]])
   
np.diag
sort执行此操作,但将结果设置为只读

In [157]: np.diag(a)                                                                                 
Out[157]: array([1., 2., 3.])
In [158]: d2 = np.diag(a)                                                                            
In [159]: d2[1] = 0                                                                                  
---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-159-64d5edb77b4c> in <module>
----> 1 d2[1] = 0

ValueError: assignment destination is read-only
In [160]: a[1,1] = 10                                                                                
In [161]: a                                                                                          
Out[161]: 
array([[ 1.,  1.,  1.],
       [ 1., 10.,  1.],
       [ 1.,  1.,  3.]])
In [162]: d2                                                                                         
Out[162]: array([ 1., 10.,  3.])
In [163]: d1                                                                                         
Out[163]: array([ 1., 10.,  3.])
[157]中的
:np.diag(a)
Out[157]:数组([1,2,3.])
In[158]:d2=np.diag(a)
In[159]:d2[1]=0
---------------------------------------------------------------------------
ValueError回溯(最近一次调用上次)
在里面
---->1 d2[1]=0
ValueError:分配目标为只读
In[160]:a[1,1]=10
在[161]中:a
出[161]:
数组([[1,1,1.],
[ 1., 10.,  1.],
[ 1.,  1.,  3.]])
In[162]:d2
Out[162]:数组([1,10,3.])
In[163]:d1
Out[163]:数组([1,10,3.])

修改
a
会改变
d2
,但我们不能反过来做。

不知何故,它对行(和列)有效:````>>row0=a[0]>>row0[0]=0>>数组([[0,1,1.],[1,1,1,1.],[1,1,1.]))“``我一直在寻找同样的功能,但要使用对角线元素。行和列都在NumPy中内置了切片覆盖。没有多维叠加。对于带有“step”参数的切片,也没有覆盖。我所知道的最后一种语言是几十年前MATLAB的前身,我理解。在这种情况下,似乎不可能直接从numpy.Right获得我想要的功能。我希望我能记住那门古老语言的名字,但那是很久以前的事了。@prune,你是在想
APL
,一种可以追溯到60年代的数学数组语言。谢谢。我来看看。如果对角线索引使用数组(高级),那么值就是一个副本。但是我相信在一个散开的数组上使用
跨步
是可能的,并且可以获得一个视图。我以后会解决细节问题。@hpaulj使用步幅是可能的(以及
einsum(“ii->I”…
所做的);只是重要的是不要在之前对数组进行解缠,因为在某些情况下,解缠确实会强制执行不必要的(用于提取对角线)副本。