某些Numpy函数返回ndarray而不是我的子类

11 投票
1 回答
1283 浏览
提问于 2025-04-16 18:41

我正在对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'>

查看fftlog10的代码,我发现它们使用了asarray(),这个函数会去掉子类,返回一个ndarray,这就解释了这个行为。因此,我的问题不是“为什么技术上会这样”,而是一个设计问题——我应该如何编写我的代码,以避免这种情况发生?

附言:我在Python和Stack Overflow上都是新手,请原谅我可能的明显错误或不当之处……

谢谢,

Guy。

1 个回答

1

我不太确定 fft 是什么,但 np.log10 是一个叫做 ufunc 的东西。下面这个页面解释了如何确定 ufunc 的输出类型:http://docs.scipy.org/doc/numpy/reference/ufuncs.html#output-type-determination

如果 fft 总是返回一个 ndarray,我也不会感到惊讶(我没有查看源代码,但 FFT 显然不符合 ufunc 的定义)。如果真是这样,你可以自己写一个包装函数,然后调用它。

撰写回答