自动调整 NumPy 记录数组大小

2 投票
2 回答
813 浏览
提问于 2025-04-16 19:52

我想创建一个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

但是,当我使用numpy.core.records.recarray的 __getitem__ 方法时,会出现一个IndexError错误:

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 个回答

2

你重写的 __getitem__ 方法没有返回任何值。

我花了很长时间才意识到这一点,真是有点吓人。

另外,正如 Petr Viktorin 指出的,你在 __init__ 调用中漏掉了 *** 操作符。

3

首先,你在调用 numpy.recarray.__init__ 的时候,缺少了星号(*):

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

其次,你在 __getitem__ 里面缺少了 return 语句:

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)

撰写回答