我正在尝试对一个 numpy 结构化数组进行子类化,以便我可以向该子类添加特殊方法。一切正常,直到我从数组中检索到单个索引。发生这种情况时,将返回一个 numpy.void 类型的对象,而不是子类的类型。 (实际上,无论是否子类化,从结构化数组中检索单个索引都会返回一个 numpy.void 类型的对象。)这是为什么呢?我怎样才能确保返回我的类的一个实例?我认为覆盖 __getitem__ 是可行的方法,但我对 ndarray 子类化不够熟悉,无法确信我不会搞砸其他事情。请指教。
这是我描述的行为示例:
import numpy as np
# The ndarray subclass
class Foo(np.ndarray):
# Do something special that uses a field of the structured array
def bar(self):
return self['BAR']
def main():
# Set up the structured array
arr = np.arange((3+2)*2,dtype=np.float64).view(dtype=np.dtype([('BAR',np.float64,3),('other',np.float64,2)]))
# Get a Foo instance using the data
obj = arr.view(Foo)
print 'type(obj): ',type(obj) # As expected: Foo object
print 'type(obj[:1]): ',type(obj[:1]) # As expected: Foo object
print 'type(obj[0]): ',type(obj[0]) # Why numpy.void???
print 'obj.bar():' # As expected
print obj.bar() # As expected
print 'obj[:1].bar():',obj[:1].bar() # As expected
print 'obj[0].bar(): ',obj[0].bar() # Causes exception: AttributeError: 'numpy.void' object has no attribute 'bar'
if __name__=="__main__":
main()
输出如下:
type(obj): <class '__main__.Foo'>
type(obj[:1]): <class '__main__.Foo'>
type(obj[0]): <type 'numpy.void'>
obj.bar():
[[ 0. 1. 2.]
[ 5. 6. 7.]]
obj[:1].bar(): [[ 0. 1. 2.]]
Traceback (most recent call last):
File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/site-packages/ipdb/__main__.py", line 138, in main
pdb._runscript(mainpyfile)
File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/pdb.py", line 1233, in _runscript
self.run(statement)
File "/Library/Frameworks/Python.framework/Versions/7.3/lib/python2.7/bdb.py", line 387, in run
exec cmd in globals, locals
File "", line 1, in
File "scratch.py", line 1, in
import numpy as np
File "scratch.py", line 25, in main
print 'obj[0].bar(): ',obj[0].bar() # Causes exception: AttributeError: 'numpy.void' object has no attribute 'bar'
AttributeError: 'numpy.void' object has no attribute 'bar'
obj[0].bar(): Uncaught exception. Entering post mortem debugging
Running 'cont' or 'step' will restart the program
最佳答案
错误与父类(super class)无关,它来自 View 和自定义数据类型:
>>> arr = np.arange((3+2)*2,dtype=np.float64).view(dtype=np.dtype([('BAR',np.float64,3),('other',np.float64,2)]))
>>> arr[0]
([0.0, 1.0, 2.0], [3.0, 4.0])
>>> type(arr[0])
<type 'numpy.void'>
关于python - 单索引到 numpy 结构化数组子类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/20056241/