Numpy:创建对称矩阵类

0 投票
1 回答
1339 浏览
提问于 2025-04-16 16:54

根据这个回答,我在用numpy编写一个简单的对称矩阵类,但遇到了一个(可能很简单的)问题。以下是有问题的代码:

import numpy as np

 class SyMatrix(np.ndarray):
    def __init__(self, arr):
        self = (arr + arr.T)/2.0 - np.diag(np.diag(arr)) 
    def __setitem__(self,(i,j), val):
        np.ndarray.__setitem__(self, (i, j), value)
        np.ndarray.__setitem__(self, (j, i), value)

除了感觉这样做不太对(我不知道给self赋值是否是个好习惯……)当我尝试创建一个新数组时,我得到了这个:

>>> foo = SyMatrix( np.zeros(shape = (2,2)))
Traceback (most recent call last):
   File "<stdin>", line 1, in <module>
TypeError: only length-1 arrays can be converted to Python scalars

我还尝试了:

import numpy as np

 class SyMatrix(np.ndarray):
    def __init__(self, n):
        self =  np.zeros(shape = (n,n)).view(SyMatrix)  
    def __setitem__(self,(i,j), val):
        np.ndarray.__setitem__(self, (i, j), value)
        np.ndarray.__setitem__(self, (j, i), value)

然后我得到了:

>>> foo = SyMatrix(2)
>>> foo
SyMatrix([  6.93581448e-310,   2.09933710e-316])
>>> 

我本来期待得到一个形状为(2,2)的数组。那我该怎么做才是正确的呢?给self赋值会有问题吗?

1 个回答

3

这里有几个问题。

  1. 当你在创建一个新的类来继承 numpy.ndarray() 时,你应该重写 __new__() 方法,而不是 __init__() 方法。你写的这一行

    foo = SyMatrix(2)
    

    实际上是用参数 2 调用了 numpy.ndarray.__new__(),这个参数和它的要求不匹配

  2. 在这里给 self 赋值其实没有任何作用。它只是创建了一个对象,并让本地的名字 self 指向这个对象。一旦函数结束,所有本地的名字都会消失。在 Python 中,赋值既不会 创建变量,也不会 改变对象;它只是把一个已经存在的对象指给一个名字。

  3. 即使解决了前两个问题,你的对称矩阵类也不会按预期工作。实际上,你需要重写很多方法,才能确保矩阵始终是对称的。

  4. (arr + arr.T)/2.0 - np.diag(np.diag(arr)) 很可能不是你想要的结果。这样做会导致对角线上总是为零。你可能想要的是 (arr + arr.T)/2.0

撰写回答