一些 Numpy 函数返回 ndarray 而不是我的子类
我对 Numpy 的 ndarray 类进行子类化,添加一些元数据和其他方法。我正在尝试按照 本文 和 那个。但是,某些 Numpy(或 Scipy)函数返回基类“ndarray”而不是我的自定义子类。其他 Numpy 函数确实返回我的子类,但我不知道差异的原因是什么。如何使所有 numpy/scipy 函数返回我的子类?这就是我所做的:
class Signal(np.ndarray):
def __new__(cls, filename):
#print "In __new__" #TEMP DEBUG
ret = np.fromfile(filename, dtype = np.int32)
ret = ret.view(cls) # convert to my class, i.e. Signal
ret.parse_filename(filename)
return ret
def __array_finalize__(self, obj):
#print "in __array_finalize__" #TEMP DEBUG
if obj is None: return # shouldn't actually happen.
# copy meta-fields from source, if it has them (otherwise put None's)
self.filename = getattr(obj, "filename", None)
self.folder = getattr(obj, "folder", None)
self.label = getattr(obj, "label", None)
self.date = getattr(obj, "date", None)
self.time = getattr(obj, "time", None)
#etc
这里有一些使用示例:
这些按预期工作 -
>>> s = Signal(filename)
>>> s2 = s[10:20]
>>> type (s2)
<class '__main__.Signal'>
>>> s3 = s + 17
>>> type (s3)
<class '__main__.Signal'>
>>> s4 = np.sqrt(s)
>>> type(s4)
<class '__main__.Signal'>
但是,这些怎么样?
>>> s5 = log10(s)
>>> type(s5)
<type 'numpy.ndarray'>
>>> s6 = np.fft.fft(s)
>>> type(s6)
<type 'numpy.ndarray'>
查看 fft
和 log10
的代码,我可以看到它们使用 asarray()
,它剥离子类并返回一个 ndarray,解释了行为。因此,我的问题不是“从技术上讲,为什么会发生这种情况”,而是更多的设计问题 - 我应该如何编写代码才能避免这种情况发生?
ps 我是 Python 和 Stack Overflow 的新手,所以请原谅任何明显的错误或不恰当的地方......
谢谢, 盖伊。
I am subclassing Numpy's ndarray class, adding some meta-data and additional methods. I'm trying to follow the instructions in this article and that one. However, some Numpy (or Scipy) functions return the base class "ndarray" instead of my custom subclass. Other Numpy functions DO return my subclass, and I don't know what's the reason for the difference. How can I make all the numpy/scipy functions return my subclass? here's what I did:
class Signal(np.ndarray):
def __new__(cls, filename):
#print "In __new__" #TEMP DEBUG
ret = np.fromfile(filename, dtype = np.int32)
ret = ret.view(cls) # convert to my class, i.e. Signal
ret.parse_filename(filename)
return ret
def __array_finalize__(self, obj):
#print "in __array_finalize__" #TEMP DEBUG
if obj is None: return # shouldn't actually happen.
# copy meta-fields from source, if it has them (otherwise put None's)
self.filename = getattr(obj, "filename", None)
self.folder = getattr(obj, "folder", None)
self.label = getattr(obj, "label", None)
self.date = getattr(obj, "date", None)
self.time = getattr(obj, "time", None)
#etc
here are some usage examples:
these work as expected -
>>> s = Signal(filename)
>>> s2 = s[10:20]
>>> type (s2)
<class '__main__.Signal'>
>>> s3 = s + 17
>>> type (s3)
<class '__main__.Signal'>
>>> s4 = np.sqrt(s)
>>> type(s4)
<class '__main__.Signal'>
however, what about these?
>>> s5 = log10(s)
>>> type(s5)
<type 'numpy.ndarray'>
>>> s6 = np.fft.fft(s)
>>> type(s6)
<type 'numpy.ndarray'>
looking into the code of fft
and log10
I can see that they use asarray()
, which strips the subclass and returns an ndarray, explaining the behavior. Therefore, my question isn't "why, technically, this happens" but more a design question - how should I write my code so this doesn't happen?
p.s. I'm a newbie both at Python and here on Stack Overflow, so please excuse any obvious mistakes or inappropriateness...
thanks,
Guy.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
我不确定
fft
,但np.log10
是 ufunc.下页解释了如何确定 ufunc 的输出类型: http://docs.scipy.org/doc/numpy/reference/ufuncs.html#output-type-determination如果
fft
总是返回一个ndarray 不过(我没有看过源代码,但 FFT 显然不符合 ufunc 的定义)。如果是这种情况,您始终可以编写自己的包装器并调用它。
I am not sure about
fft
, butnp.log10
is a ufunc. The following page explains how the output type of a ufunc is determined: http://docs.scipy.org/doc/numpy/reference/ufuncs.html#output-type-determinationIt wouldn't surprise me if
fft
always returned anndarray
though (I haven't looked at the source code, but the FFT clearly doesn't fit the definition of a ufunc). If that's the case, you can always write your own wrapper and call that instead.