2

I want to subclass numpy recarrays and being able to create views from that class. For example:

_Theta = np.dtype([('v', '<f8'), ('a', '<f8'), ('w', '<f8')])

class Theta(np.recarray):
    ''' Defines a class for the parameters of a DDM model. '''

    def __new__(clc, shape=1):

        return np.recarray.__new__(clc, shape, _Theta)

If I create an instance it produces the results that I want.

In [12]: r = Theta()

In [13]: r
Out[13]: 
Theta([(6.91957786449907e-310, 2.9958354e-316, 2.0922526e-316)], 
      dtype=[('v', '<f8'), ('a', '<f8'), ('w', '<f8')])

However, if I try to create a view of my class I get the following:

In [11]: np.zeros(3).view(Theta).a
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-11-b9bdab6cd66c> in <module>()
----> 1 np.zeros(3).view(Theta).a

/usr/lib/python2.7/dist-packages/numpy/core/records.pyc in __getattribute__(self, attr)
    414             res = fielddict[attr][:2]
    415         except (TypeError, KeyError):
--> 416             raise AttributeError("record array has no attribute %s" % attr)
    417         obj = self.getfield(*res)
    418         # if it has fields return a recarray, otherwise return

AttributeError: record array has no attribute a

Is it possible to create views of an array such that I can address them with the attributes that I defined for Theta? (I think this should be done somehow through the array_finalize method, but I don't know how).

eaponte
  • 409
  • 5
  • 15

1 Answers1

0

You could do an implementation like this:

import numpy as np

class Theta(np.recarray):
    ''' Defines a class for the parameters of a DDM model.

    '''
    def __new__(clc, *args, **kwargs):
        a = np.atleast_2d(np.array(*args, **kwargs))
        dtype = np.dtype([('v', '<f8'), ('a', '<f8'), ('w', '<f8')])
        r = np.recarray(shape=a.shape[0], dtype=dtype)
        r.v = a[:,0]
        r.a = a[:,1]
        r.w = a[:,2]
        return r.view(Theta)

r = Theta([[1,2,3],[1,2,3]])

such that:

a = Theta(np.zeros(3))

will do what you wanted to do... This would perhaps require an additional check like :

assert a.shape[1] % 3 == 0
Saullo G. P. Castro
  • 56,802
  • 26
  • 179
  • 234