在numpy中改变矩阵对角线的值

时间:2012-03-31 18:35:58

标签: python numpy

如何在numpy中更改矩阵对角线的值?

我检查了Numpy modify ndarray diagonal,但是那个函数没有在numpy v 1.3.0中实现。

假设我们有一个np.array X,我想将对角线的所有值都设置为0.

7 个答案:

答案 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)

最小。代码。

X[np.diag_indices_from(X)] = 0.

screenshot

答案 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