Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

A more compact __repr__ for my numpy array?

Tags:

python

numpy

When I show an array, the default __repr__() method for ndarray objects is too big for what I would like to do:

a = np.eye(32)
b = {'hello':42, 'array':a}
b

produces:

{'array': array([[ 1.,  0.,  0., ...,  0.,  0.,  0.],
       [ 0.,  1.,  0., ...,  0.,  0.,  0.],
       [ 0.,  0.,  1., ...,  0.,  0.,  0.],
   ..., 
       [ 0.,  0.,  0., ...,  1.,  0.,  0.],
       [ 0.,  0.,  0., ...,  0.,  1.,  0.],
       [ 0.,  0.,  0., ...,  0.,  0.,  1.]]), 'hello': 42}

I tried an ugly solution, reassigning __repr__:

def wow():
    return "wow!"

a.__repr__ = wow

which yields an attribution error and I am not surprised:

Traceback (most recent call last):
  File "<pyshell#11>", line 1, in <module>
    a.__repr__ = wow
AttributeError: 'numpy.ndarray' object attribute '__repr__' is read-only

I can make a class with a custom repr that is what I would like:

class NP(object):
    def __init__(self, a):
        self.a = a
    def __repr__(self):
        s0, s1 = self.a.shape
        dtp    = self.a.dtype
        return '{}x{} {}'.format(s0, s1, dtp)

A = NP(a)
A

now yields:

32x32 float64

but the tiny problem is that I would now have to access the attribute everywhere. A.sum() fails, A.a.sum() works.

Is there a way to do this using NumPy directly?

like image 908
uhoh Avatar asked Sep 19 '25 07:09

uhoh


1 Answers

Use np.set_string_function:

>>> def __repr__(self):
...     s0, s1 = self.shape                                                               
...     dtp    = self.dtype                                                                   
...     return '{}x{} {}'.format(s0, s1, dtp)                                                                   
...                                                                                                                 
>>> np.set_string_function(__repr__)                               
>>> np.identity(5)                                                 
5x5 float64                                                                                                         

For more advanced display, you may want to have a look at reprlib.

If on the other hand all you want is to make it a bit shorter np.set_printoptions may be your easiest option.

If you need this to apply only to a subset of arrays, then subclassing may indeed be your best option. I'm not sure, though, what the current status of subclassing is with numpy. It used to be fraught with subtleties to say the least.

>>> class myarray(np.ndarray):                                                                            
...    def __repr__(self):                                                                                
...        return "wow!"
...                                                                                                                 
>>> np.identity(5).view(myarray)                                                                                  
wow!                           
like image 71
Paul Panzer Avatar answered Sep 20 '25 22:09

Paul Panzer