如何在numpy中更改矩阵对角线的值?
我检查了Numpy modify ndarray diagonal,但是那个函数没有在numpy v 1.3.0中实现。
假设我们有一个np.array X,我想将对角线的所有值都设置为0.
答案 0 :(得分:41)
你试过numpy.fill_diagonal
吗?请参阅以下answer和此discussion。或者文档中的以下内容(虽然目前已损坏):
http://docs.scipy.org/doc/numpy/reference/generated/numpy.fill_diagonal.html
答案 1 :(得分:13)
如果你使用的是没有fill_diagonal
的numpy版本(right way将对角线设置为常量)或diag_indices_from
,你可以很容易地做到这一点使用数组切片:
# assuming a 2d square array
n = mat.shape[0]
mat[range(n), range(n)] = 0
这比Python中的显式循环快得多,因为循环在C中发生并且可能被矢量化。
关于这一点的一个好处是你也可以用一个元素列表填充对角线,而不是一个常量值(如diagflat
,但是用于修改现有矩阵而不是创建一个新矩阵)。例如,这会将矩阵的对角线设置为0,1,2,...:
# again assuming 2d square array
n = mat.shape[0]
mat[range(n), range(n)] = range(n)
如果你需要支持更多的数组形状,这就更复杂了(这就是为什么fill_diagonal很好......):
m[list(zip(*map(range, m.shape)))] = 0
(仅在Python 3中需要list
调用,其中zip
返回迭代器。)
答案 2 :(得分:10)
这是另一种做到这一点的好方法。如果你想要一个主要对角线使用的一维视图:
A.ravel()[:A.shape[1]**2:A.shape[1]+1]
对于第i个超对角线使用:
A.ravel()[i:max(0,A.shape[1]-i)*A.shape[1]:A.shape[1]+1]
对于第i个子对角线使用:
A.ravel()[A.shape[1]*i:A.shape[1]*(i+A.shape[1]):A.shape[1]+1]
或者一般来说,对于主对角线为0的第i个对角线,子对角线为负,超对角线为正,请使用:
A.ravel()[max(i,-A.shape[1]*i):max(0,(A.shape[1]-i))*A.shape[1]:A.shape[1]+1]
这些是视图而不是副本,因此它们在提取对角线时运行得更快,但对新数组对象所做的任何更改都将应用于原始数组。 在我的机器上,当将主对角线设置为常数时,它们比fill_diagonal函数运行得更快,但情况可能并非总是如此。它们也可用于将一组值分配给对角线,而不仅仅是一个常量。
注意:对于小数组,使用NumPy数组的flat
属性可能会更快。
如果速度是一个主要问题,那么将A.shape[1]
作为局部变量是值得的。
此外,如果数组不连续,ravel()
将返回一个副本,因此,为了将值分配给跨步切片,有必要创造性地切片用于生成跨步切片的原始数组(如果它是连续的)或使用flat
属性。
此外,最初计划在NumPy 1.10及之后的对角线'数组方法将返回视图而不是副本。 尽管如此,这种变化还没有完成,但希望在某些时候这个获得观点的技巧将不再是必要的。 见http://docs.scipy.org/doc/numpy-dev/reference/generated/numpy.diagonal.html
答案 3 :(得分:7)
答案 4 :(得分:2)
def replaceDiagonal(matrix, replacementList):
for i in range(len(replacementList)):
matrix[i][i] = replacementList[i]
其中n在n x n矩阵中的大小为n。
答案 5 :(得分:1)
>>> a = numpy.random.rand(2,2)
>>> a
array([[ 0.41668355, 0.07982691],
[ 0.60790982, 0.0314224 ]])
>>> a - numpy.diag(numpy.diag(a))
array([[ 0. , 0.07982691],
[ 0.60790982, 0. ]])
答案 6 :(得分:1)
您可以执行以下操作。
假设你的矩阵是4 * 4矩阵。
indices_diagonal = np.diag_indices(4)
yourarray[indices_diagonal] = Val