Автоматическое изменение размера NumPy recarray - PullRequest
2 голосов
/ 20 июня 2011

Я хотел бы создать подкласс numpy.recarray, который автоматически изменяет размер при добавлении данных в строку за пределами текущей длины.

Код ниже делает большую часть того, что я хочу.

class autorecarray(numpy.recarray):

   def __init__(self,*args,**kwargs):
      self._increment = 1
      numpy.recarray.__init__(self,args,kwargs)

   def __setitem__(self,ind,y):
      try: 
         numpy.recarray.__setitem__(self,ind,y)
      except IndexError:
         self.resize((self.__len__()+self._increment,),refcheck=False)
         self.__setitem__(ind,y)

Отлично подходит для этого варианта использования:

a = utils.autorecarray((1,),formats=['i4','i4'])
a[1] = (1,2) # len(a) will now be 2

Однако это использование вызовет ошибку IndexError для метода numpy.core.records.recarray __getitem__:

a[2]['f1'] = 3

Моей первоначальной попыткой было также переопределить метод __getitem__ в моем подклассе, но этот код не работает.

def __getitem__(self,ind):
      try:
         numpy.recarray.__getitem__(self,ind)
      except IndexError:
         self.resize((self.__len__() + self._increment,),refcheck=False)
         self.__getitem__(ind)

Он автоматически расширяет массив, но теперь каждый элемент в массиве равен None и не может быть изменен.

Может кто-нибудь сказать мне, что я делаю не так?

Ответы [ 2 ]

3 голосов
/ 20 июня 2011

Прежде всего вам не хватает звездочек в вызове numpy.recarray.__init__:

def __init__(self, *args, **kwargs):
    self._increment = 1
    numpy.recarray.__init__(self, *args, **kwargs)

А во-вторых, вам не хватает return операторов в __getitem__:

def __getitem__(self,ind):
    try:
        return numpy.recarray.__getitem__(self,ind)
    except IndexError:
        self.resize((self.__len__() + self._increment,),refcheck=False)
        return self.__getitem__(ind)
2 голосов
/ 20 июня 2011

Ваше переопределенное значение __getitem__ не возвращает значение.

Мне понадобилось очень много времени, чтобы понять это.

Также, как указывает Петр Викторин , вы исключили операторы * и ** в своем вызове __init__.

...