numpy的子类的数组



我有一个问题。问题是:我想创建一个numpy数组的子类,然后创建一个该类型对象的数组。当我引用数组中的一个项时,我希望它仍然是该子类的一个实例。相反,它是numpy数组的一个实例。

下面是失败的测试:

import numpy as np

class ImageWrapper(np.ndarray):
    def __new__(cls, image_data):
        assert image_data.ndim in (2, 3)
        return image_data.view(cls)
    @property
    def n_colours(self): 
        return 1 if self.ndim==2 else self.shape[2]

n_frames = 10
frames = [ImageWrapper(np.random.randint(255, size = (20, 15, 3)).astype('uint8')) for _ in xrange(n_frames)]
video = np.array(frames)
assert video[0].n_colours == 3

给出:AttributeError: 'numpy. 'Ndarray '对象没有属性' n_colors '

我怎样才能使它工作?

事情已经尝试过了:

  • 在构造视频时设置subok=True -这只适用于从子类对象的单个实例构造数组时,而不是一个列表。
  • 设置dtype=object或dtype=ImageWrapper无效

我知道我可以把video做成一个列表,但出于其他原因,最好还是把它作为一个numpy数组。

无论您想要实现什么,都可能有比创建narray子类更好的方法。但考虑到这一点,你可以让你的数组的类型是object,尽管你在创建它的时候必须小心。如此:

>>> video = np.empty((len(frames),), dtype=object)
>>> video[:] = frames
>>> video[0].n_colours
3

但这不是:

>>> video = np.array(frames, dtype=object)
>>> video[0].n_colours
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'numpy.ndarray' object has no attribute 'n_colours'

numpy。数组还不够复杂,无法处理这种情况。subok=True告诉函数通过子类传递,但是你没有传递给它一个narray的子类,你传递给它一个列表(它恰好被一个narray子类的实例填充)。您可以通过以下操作获得您所期望的内容:

import numpy as np

class ImageWrapper(np.ndarray):
    def __new__(cls, image_data):
        assert 2 <= image_data.ndim <= 4
        return image_data.view(cls)
    @property
    def n_colours(self): 
        return 1 if self.ndim==2 else self.shape[-1]

n_frames = 10
frame_shape = (20, 15, 3)
video = ImageWrapper(np.empty((n_frames,) + frame_shape, dtype='uint8'))
for i in xrange(n_frames):
    video[i] = np.random.randint(255, size=(20, 15, 3))
assert video[0].n_colours == 3

注意我必须更新ImageWrapper以允许4d数组作为输入

相关内容

  • 没有找到相关文章

最新更新