基于this answer我在python中用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])
>>>
我期望一个shape=(2,2)
的数组。做我正在做的事情的正确方法是什么?分配给self
有问题?
答案 0 :(得分:3)
这里有一些问题。
在subclassing numpy.ndarray()
时,您应该覆盖__new__()
,而不是__init__()
。你的行
foo = SyMatrix(2)
实际上使用参数2调用numpy.ndarray.__new__()
,与its signature不兼容。
分配给self
在这里绝对没有任何意义。它只是创建一个对象,并使本地名称self
指向此对象。函数退出后,将删除所有本地名称。在Python中分配既不创建变量,也不改变对象;它只是将现有对象分配给名称。
即使在修复最后两个问题时,对称矩阵类也无法按预期工作。您需要覆盖几十种方法来确保矩阵始终是对称的。
(arr + arr.T)/2.0 - np.diag(np.diag(arr))
很可能不是你想要的。它在对角线上总是有零。您可能需要(arr + arr.T)/2.0
。