修改2d-numpy数组的主对角线的一部分

时间:2017-08-22 07:46:36

标签: python arrays numpy

我在执行以下任务时遇到了问题。

假设我们有一个矩阵,如下所示:

Mat = np.array([
    [11, 12, 13, 14, 15], \
    [21, 22, 23, 24, 25], \
    [31, 32, 33, 34, 35], \
    [41, 42, 43, 44, 45], \
    [51, 52, 53, 54, 55]])

我想要做的是将条目22,33和44替换为我之前计算的不同。我知道我可以用for循环做这个,但我认为必须有一个更优雅的方式。

我有这样的想法:

  1. 从[1,1]到[-2,-2]中选择主对角线并将其另存为数组。
  2. 以所需方式修改此数组。
  3. 将修改后的数组保存为矩阵主对角线的一部分。
  4. 我找到了 np.diagonal()来获得对角线并且到目前为止:

    Mat = np.array([
    [11, 12, 13, 14, 15], \
    [21, 22, 23, 24, 25], \
    [31, 32, 33, 34, 35], \
    [41, 42, 43, 44, 45], \
    [51, 52, 53, 54, 55]])
    
    print(Mat)
    
    snipA = Mat.diagonal()
    snipB = snipA[1:len(snipA)-1]
    print(snipA)
    print(snipB)
    

    现在有两个问题。首先,我无法以任何方式修改snipB。我得到错误:"输出数组是只读的"。其次,如何将修改后的snipB再次保存到矩阵中?

    感谢任何帮助。

2 个答案:

答案 0 :(得分:2)

您可以索引和修改对角线的一部分,如下所示:

>>> subdiag = np.arange(1, len(mat)-1)
>>> mat[subdiag, subdiag]
array([22, 33, 44])
>>> mat[subdiag, subdiag] = 0
>>> mat
array([[11, 12, 13, 14, 15],
       [21,  0, 23, 24, 25],
       [31, 32,  0, 34, 35],
       [41, 42, 43,  0, 45],
       [51, 52, 53, 54, 55]])
>>>
>>> mat[subdiag, subdiag] = [22, 33, 44]
>>> mat
array([[11, 12, 13, 14, 15],
       [21, 22, 23, 24, 25],
       [31, 32, 33, 34, 35],
       [41, 42, 43, 44, 45],
       [51, 52, 53, 54, 55]])

答案 1 :(得分:0)

您也可以使用numpy 1.10

后的einsum来执行此操作
np.einsum('ii->i', mat)[1:-1] = 0

mat 
array([[11, 12, 13, 14, 15],
       [21,  0, 23, 24, 25],
       [31, 32,  0, 34, 35],
       [41, 42, 43,  0, 45],
       [51, 52, 53, 54, 55]])