Numpy子类属性切片

时间:2013-05-02 16:22:11

标签: python numpy slice

Myclass是一个numpy.ndarray子类,用于表示随时间变化的一组图像。每个图像都有一组元数据,如时间,环境温度和相机温度。我已将这些元数据存储在字典列表中,以便每个字典对应于数组中的一个层(myclass.metadata[0]是与myclass[0]中的图像对应的字典。)

我还重载getattr()以使字典中的项目可以通过其密钥访问,以便myclass.etemp产生例如[24.9, 25.0, 25.1]

当我对Myclass对象进行切片时,如何实现我的属性数组以相同的方式切片?

现在如果我myobject[1].etemp,我会[24.9, 25.0, 25.1],但我需要[25.0]

这是我的班级:

class Stack(numpy.ndarray):
    props= [
            'version',
            'width',
            'height',
            'shotrange',
            'calibrange',
            'unit',
            'irb_fname',
            'fidx',
            'distance',
            'etemp',
            'zoom',
            'ctemp',
            'date',
            'recdate',
            'rectime',
            ]

    def __new__(cls, input_array, mdata=None):
        obj = numpy.asarray(input_array).view(cls)
        if isinstance(mdata, collections.Iterable): # when reading from text file
            obj.mdata = mdata
        else:
            obj.mdata = [arr.mdata[0] for arr in input_array] # when combining Stack-type objects
        return obj

    def __array_finalize__(self, obj):
        if obj is None: return
        self.mdata = getattr(obj, 'mdata', None)

    def __getattr__(self, name):
        print(numpy.shape(self))
        if numpy.rank(self) < 3: # we're looking at a single slice
            pass
        if name == 'starttime':
            return self.mdata[0]['date']
        elif name == 'time':
            return [(item['date'] - self.mdata[0]['date']).total_seconds() for item in self.mdata]
        elif name in Stack.props:
            return [item[name] for item in self.mdata]
        else:
            raise AttributeError

我需要做些什么才能实现这种行为?或者还有其他更好的方法来存储元数据吗?

2 个答案:

答案 0 :(得分:1)

您需要覆盖__getitem__方法。

class Foo(object):
    def __getitem__(self,items):
        print items

f = Foo()
f[1,2,3]
f[1:3]
f[1,1:3,2:3]

返回:

1
(1, 2, 3)
slice(1, 3, None)
(1, slice(1, 3, None), slice(2, 3, None))

getitem 中,您需要适当地对属性进行切片以及处理上述情况。

答案 1 :(得分:0)

让你的属性附加到数组中的对象,而不是你的数组可能有帮助。