Python Numpy子类属性切片

Python Numpy子类属性切片,python,numpy,slice,Python,Numpy,Slice,Myclass是一个numpy.ndarray子类,用于表示一组随时间变化的图像。每个图像都有一组元数据,如时间、环境温度和相机温度。我已将这些元数据存储在字典列表中,因此每个字典都对应于数组中的一个层(myclass.metadata[0]是对应于myclass[0]中图像的字典) 我还重载了getattr(),使字典中的项可以通过它们的键访问,因此myclass.etemp产生了例如[24.9,25.0,25.1] 当我切片Myclass对象时,如何实现属性数组以相同的方式切片 现在如果我做

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
类堆栈(numpy.ndarray): 道具=[ “版本”, “宽度”, “高度”, “射程”, “calibrange”, "单位",, “irb_fname”, “fidx”, “距离”, “etemp”, “缩放”, “ctemp”, “日期”, “记录日期”, '矩形', ] def _u新建(cls,输入数组,mdata=None): obj=numpy.asarray(输入数组).view(cls) 如果isinstance(mdata,collections.Iterable):#从文本文件读取时 obj.mdata=mdata 其他: obj.mdata=[arr.mdata[0]表示输入数组中的arr]#组合堆栈类型对象时 返回obj def _;阵列_;最终确定___;(自身,obj): 如果obj为无:返回 self.mdata=getattr(obj,'mdata',无) def _ugetattr _;(self,name): 打印(numpy.shape(自身)) 如果numpy.rank(self)<3:#我们只看一个片段 通过 如果名称==“开始时间”: 返回self.mdata[0]['date'] elif名称==“时间”: 返回[(item['date']-self.mdata[0]['date'])。self.mdata中项目的总秒数() Stack.props中的elif名称: 返回[self.mdata中项目的项目[名称] 其他: 提高属性错误
我需要做什么来实现这种行为?或者是否有其他更好的方法来存储元数据?

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

您需要重写
\uu getitem\uuuu
方法

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))

\uuuu getitem\uuuuu
中,您需要适当地分割属性,并处理上述情况。

还可能需要查看PyTables,这是一种存储数据和相关元数据的好方法。超快也!我已经在使用h5py在磁盘上存储数据了,但是我会不会失去像myclass[0,0,0]和myclass[0:3]这样的功能?这是我将NdarayTank you子类化的主要原因,这是我失败的地方,但现在问题似乎已经解决了。我无意中发现了
numpy.ndarray.\uuuu array\uuuu()
。我的
\uu getitem\uu()
现在检查
self
是否为等级3,然后才修改元数据。每次调用都会返回一个新的堆栈对象。此外,我还必须修改
\uuuu getslice\uuuu(self,I,j)
以调用
self[I:j:None]
,这样切片就成为扩展切片并传递给
\uuu getitem\uuuu()
。默认情况下不应该发生这种情况吗?为了向后兼容,在
\uuuuuu getitem\uuuuu
之前会尝试
\uuuuu getslice\uuuuu
。因此,如果基类实现了
\uuu getslice\uuu
,那么您也必须重写它。