子类化 numpy ndarray 问题
我想对 numpy ndarray 进行子类化。但是,我无法更改数组。为什么 self = ...
不改变数组?谢谢。
import numpy as np
class Data(np.ndarray):
def __new__(cls, inputarr):
obj = np.asarray(inputarr).view(cls)
return obj
def remove_some(self, t):
test_cols, test_vals = zip(*t)
test_cols = self[list(test_cols)]
test_vals = np.array(test_vals, test_cols.dtype)
self = self[test_cols != test_vals] # Is this part correct?
print len(self) # correct result
z = np.array([(1,2,3), (4,5,6), (7,8,9)],
dtype=[('a', int), ('b', int), ('c', int)])
d = Data(z)
d.remove_some([('a',4)])
print len(d) # output the same size as original. Why?
I would like to subclass numpy ndarray. However, I cannot change the array. Why self = ...
does not change the array? Thanks.
import numpy as np
class Data(np.ndarray):
def __new__(cls, inputarr):
obj = np.asarray(inputarr).view(cls)
return obj
def remove_some(self, t):
test_cols, test_vals = zip(*t)
test_cols = self[list(test_cols)]
test_vals = np.array(test_vals, test_cols.dtype)
self = self[test_cols != test_vals] # Is this part correct?
print len(self) # correct result
z = np.array([(1,2,3), (4,5,6), (7,8,9)],
dtype=[('a', int), ('b', int), ('c', int)])
d = Data(z)
d.remove_some([('a',4)])
print len(d) # output the same size as original. Why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您没有得到预期结果的原因是您在方法
remove_some
中重新分配了self
。您只是创建一个新的局部变量self
。如果你的数组形状不改变,你可以简单地做 self[:] = ... 并且你可以保留对 self 的引用,一切都会好起来的,但你正在尝试改变形状自我
。这意味着我们需要重新分配一些新的内存并更改我们引用self
时指向的位置。我不知道该怎么做。我认为可以通过
__array_finalize__
或__array__
或__array_wrap__
来实现。但我所尝试的一切都不尽如人意。现在,有另一种方法可以解决这个问题,它不需要子类化 ndarray 。您可以创建一个新类,保留一个 ndarray 属性,然后覆盖所有常用的
__add__
、__mul__
等。像这样:嗯,您得到了图片。重写所有操作符是很痛苦的,但从长远来看,我认为更灵活。
您必须仔细阅读本文才能正确执行此操作。有像 __array_finalize__ 之类的方法需要在正确的时间调用来进行“清理”。
The reason you are not getting the result you expect is because you are re-assigning
self
within the methodremove_some
. You are just creating a new local variableself
. If your array shape were not to change, you could simply do self[:] = ... and you could keep the reference toself
and all would be well, but you are trying to change the shape ofself
. Which means we need to re-allocate some new memory and change where we point when we refer toself
.I don't know how to do this. I thought it could be achieved by
__array_finalize__
or__array__
or__array_wrap__
. But everything I've tried is falling short.Now, there's another way to go about this that doesn't subclass
ndarray
. You can make a new class that keeps an attribute that is an ndarray and then override all the usual__add__
,__mul__
, etc.. Something like this:Well, you get the picture. It's a pain to override all the operators, but in the long run, I think more flexible.
You'll have to read this thoroughly to do it right. There are methods like
__array_finalize__
that need to be called a the right time to do "cleanup".也许将其设为函数,而不是方法:
或者,如果您希望将其作为方法,
这里的关键区别是
remove_some
不会尝试修改self
,它仅返回Data
的新实例。Perhaps make this a function, rather than a method:
Or, if you want it as a method,
The key difference here is that
remove_some
does not try to modifyself
, it merely returns a new instance ofData
.我尝试做同样的事情,但是子类化 ndarray 确实非常复杂。
如果您只需要添加一些功能,我建议创建一个将数组存储为属性的类。
I tried to do the same, but it is really very complex to subclass ndarray.
If you only have to add some functionality, I would suggest to create a class which stores the array as attribute.