2016-09-06 2 views
0

Ich habe eine Unterklasse von einem numpy.recarray gemacht. Der Zweck der Klasse besteht darin, ein schönes Drucken für Aufzeichnungsarrays bereitzustellen, während die Datensatzarrayfunktionalität beibehalten wird. HierErben von numpy.recarray, __unicode__ Problem

ist der Code:

import numpy as np 
import re 

class TableView(np.recarray): 

    def __new__(cls,array): 
     return np.asarray(array).view(cls) 

    def __str__(self): 
     return self.__unicode__().encode("UTF-8") 

    def __repr__(self): 
     return self.__unicode__().encode("UTF-8") 

    def __unicode__(self): 

     options = np.get_printoptions() 
     nrows = len(self) 

     print "unicode called" 

     if nrows > 2*options['edgeitems']: 
      if nrows > options['threshold']: 
       nrows = 2*options['edgeitems'] + 1 

     ncols = len(self.dtype) 

     fields = self.dtype.names 

     strdata = np.empty((nrows + 1,ncols),dtype='S32') 
     strdata[0] = fields 

     np_len = np.vectorize(lambda x: len(x)) 
     maxcolchars = np.empty(ncols,dtype='i4') 

     for i, field in enumerate(fields): 
      strdata[1:,i] = re.sub('[\[\]]','',np.array_str(self[field])).split() 
      maxcolchars[i] = np.amax(np_len(strdata[:,i])) 

     rowformat = ' '.join(["{:>%s}" % maxchars for maxchars in maxcolchars]) 
     formatrow = lambda row: (rowformat).format(*row) 
     strdata = np.apply_along_axis(formatrow,1,strdata) 

     return '\n'.join(strdata) 

Hier ist, wie es druckt:

In [3]: x = np.array([(22, 2, -1000000000.0, 2000.0), (22, 2, 400.0, 2000.0), 
    ...: (22, 2, 500.0, 2000.0), (44, 2, 800.0, 4000.0), (55, 5, 900.0, 5000.0), 
    ...: (55, 5, 1000.0, 5000.0), (55, 5, 8900.0, 5000.0), 
    ...: (55, 5, 11400.0, 5000.0), (33, 3, 14500.0, 3000.0), 
    ...: (33, 3, 40550.0, 3000.0), (33, 3, 40990.0, 3000.0), 
    ...: (33, 3, 44400.01213545, 3000.0)], 
    ...:   dtype=[('subcase', '<i4'), ('id', '<i4'), ('vonmises', '<f4'), ('maxprincipal', '<f4')]) 

In [6]: TableView(x) 
unicode called 
Out[6]: 
subcase id  vonmises maxprincipal 
    22 2 -1.00000000e+09  2000. 
    22 2 4.00000000e+02  2000. 
    22 2 5.00000000e+02  2000. 
    44 2 8.00000000e+02  4000. 
    55 5 9.00000000e+02  5000. 
    55 5 1.00000000e+03  5000. 
    55 5 8.90000000e+03  5000. 
    55 5 1.14000000e+04  5000. 
    33 3 1.45000000e+04  3000. 
    33 3 4.05500000e+04  3000. 
    33 3 4.09900000e+04  3000. 
    33 3 4.44000117e+04  3000. 

Aber das funktioniert nicht, wenn ich nur eine Zeile zu drucken:

In [7]: TableView(x)[0] 
Out[7]: (22, 2, -1000000000.0, 2000.0) 

Es funktioniert für mehrere Zeilen:

In [8]: TableView(x)[0:1] 
unicode called 
Out[8]: 
subcase id  vonmises maxprincipal 
    22 2 -1.00000000e+09  2000. 

Bei der weiteren Untersuchung:

In [10]: type(TableView(x)[0]) 
Out[10]: numpy.record 

In [11]: type(TableView(x)[0:1]) 
Out[11]: __main__.TableView 

Wie kann ich ein numpy.record von Tableview die gleiche Unicode haben?

Antwort

1

Ihre Diagnose ist richtig. Ein einzelnes Element dieser Klasse ist ein record, kein Tableview Array.

Und Indizierung mit einer Scheibe oder Liste, [0:1] oder [[0]], ist die sofortige Lösung.

Der Versuch, Unterklasse np.record und Ändern der Elemente der Tableview scheint kompliziert.

Sie könnten versuchen, die __getitem__ Methode anzupassen. Dies wird beim Indexieren des Arrays aufgerufen.

Es endet mit:

else: 
     # return a single element 
     return obj 

Eine modifizierte Version könnte ein einzelnes Element zurückgeben eine Tabellen- statt

 return Tableview([obj]) 

Aber das könnte eine Art endloser Rekursion produzieren, die Sie von zu halten Elementen wie regelmäßige Aufzeichnungen zugreifen .

Sonst möchten Sie vielleicht nur mit der Schnittindexierung leben.

+0

Es ist einfacher, mit TableView (x) [[0]] auf die Daten zuzugreifen. – snowleopard