Numpy:创建对称矩阵类
根据这个回答,我在用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
这里有几个问题。
当你在创建一个新的类来继承
numpy.ndarray()
时,你应该重写__new__()
方法,而不是__init__()
方法。你写的这一行foo = SyMatrix(2)
实际上是用参数 2 调用了
numpy.ndarray.__new__()
,这个参数和它的要求不匹配。在这里给
self
赋值其实没有任何作用。它只是创建了一个对象,并让本地的名字self
指向这个对象。一旦函数结束,所有本地的名字都会消失。在 Python 中,赋值既不会 创建变量,也不会 改变对象;它只是把一个已经存在的对象指给一个名字。即使解决了前两个问题,你的对称矩阵类也不会按预期工作。实际上,你需要重写很多方法,才能确保矩阵始终是对称的。
(arr + arr.T)/2.0 - np.diag(np.diag(arr))
很可能不是你想要的结果。这样做会导致对角线上总是为零。你可能想要的是(arr + arr.T)/2.0
。