2013-05-02 2 views
1

Myclass - это подкласс numpy.ndarray, предназначенный для представления набора изображений, которые меняются со временем. Для каждого изображения есть набор метаданных, таких как время, температура окружающей среды и температура камеры. Я сохранил эти метаданные в списке словарей, поэтому каждый словарь соответствует слою в массиве (myclass.metadata[0] - это словарь, соответствующий изображению в myclass[0]).Обрезка атрибутов подкласса Numpy

Я также перегрузил 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 

Что мне нужно сделать, чтобы реализовать такое поведение? Или есть другой лучший способ хранения метаданных?

+0

Также может потребоваться изучить PyTables, хороший способ хранения данных и связанных метаданных. Супер быстрый также! – reptilicus

+0

Я уже использую h5py для хранения данных на диске – karlson

ответ

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, вам нужно нарезать атрибуты соответствующей, а также обработка вышеуказанных случаев.

+0

Спасибо, вот что я провалил, но теперь, похоже, проблема решена. Я наткнулся на 'numpy.ndarray .__ array __()'. Мой '__getitem __()' проверяет теперь, если 'self' имеет ранг 3 и только затем изменяет метаданные. Новый объект Stack возвращается для каждого вызова. – karlson

+0

Также мне пришлось изменить '__getslice __ (self, i, j)' для вызова 'self [i: j: None]', так что срезы становятся расширенными срезами и передаются '__getitem __()'. Разве это не должно происходить по умолчанию? – karlson

+0

Для обратной совместимости '__getslice__' проверяется перед' __getitem__'. Поэтому, если базовый класс реализует '__getslice__', вам также придется переопределить это. – mhsmith

0

Связаны ли ваши объекты с объектами в массиве, а не с вашим массивом.

+0

Но разве я не потеряю способность делать что-то вроде myclass [0,0,0] и myclass [0: 3]? Это была моя основная причина для подкласса ndarray. – karlson

Смежные вопросы