Python 获取影响原始数组的2D numpy数组的对角线
我有一个2D numpy数组。我想通过创建其对角线元素的数组并修改对角线数组来修改它,以便这些更改反映在原始2D数组上 我试过: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.]) >>
>>> 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”…
所做的);只是重要的是不要在之前对数组进行解缠,因为在某些情况下,解缠确实会强制执行不必要的(用于提取对角线)副本。