Numpy:创建对称矩阵类
基于 这个答案 我正在用 numpy 在 python 中为对称矩阵编写一个简单的类,但是我我遇到了(可能是一个非常简单的)问题。这是有问题的代码:
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
有问题吗?
based on this answer I was coding a simple class for symmetric matrices in python with numpy, but I'm having (probably a very simple) problem. This is the problematic code:
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)
Besides this feeling wrong (I don't know if assigning to self
is a good practice...) When I try to create a new array I get this:
>>> 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
I also tried:
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)
And then I get:
>>> foo = SyMatrix(2)
>>> foo
SyMatrix([ 6.93581448e-310, 2.09933710e-316])
>>>
where I expected an array with shape=(2,2)
. What's the correct way to do what I'm trying to do? Is assigning to self
problematic?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这里有几个问题。
当子类化
numpy.ndarray()
时,您应该覆盖__new__()
,而不是__init__()
。你的线路实际上是用参数2调用
numpy.ndarray.__new__()
,与其签名。分配给
self
在这里绝对没有任何作用。它只是创建一个对象并使本地名称 self 指向该对象。一旦函数退出,所有本地名称都会被删除。 Python 中的赋值既不创建变量,也不改变对象;它只是为现有对象分配一个名称。即使解决了最后两个问题,您的对称矩阵类也不会按预期工作。实际上,您需要覆盖数十种方法才能确保矩阵始终对称。
(arr + arr.T)/2.0 - np.diag(np.diag(arr))
很可能不是您想要的。对角线上总是有零。您可能需要(arr + arr.T)/2.0
。There are a few issues here.
When subclassing
numpy.ndarray()
, you should overwrite__new__()
, not__init__()
. Your lineactually calls
numpy.ndarray.__new__()
with the parameter 2, incompatible with its signature.Assigning to
self
does absolutely nothing here. It just creates an object and makes the local nameself
point to this object. As soon as the function exits, all local names are dropped. Assignment in Python neither creates variables, nor does it alter objects; it just assigns an existing object to a name.Even when fixing the last two issues, your symmetric matrix class won't work as expected. There are literally dozens of methods you would need to overwrite to ensure that the matrix is always symmetric.
(arr + arr.T)/2.0 - np.diag(np.diag(arr))
most probably isn't what you want. It will always have zeros on the diagonal. You probably want(arr + arr.T)/2.0
.