@@ -126,6 +126,8 @@ class DuplicateWarning(Warning):
126
126
# table class map
127
127
_TABLE_MAP = {
128
128
u ('generic_table' ) : 'GenericTable' ,
129
+ u ('appendable_series' ) : 'AppendableSeriesTable' ,
130
+ u ('appendable_multiseries' ): 'AppendableMultiSeriesTable' ,
129
131
u ('appendable_frame' ) : 'AppendableFrameTable' ,
130
132
u ('appendable_multiframe' ) : 'AppendableMultiFrameTable' ,
131
133
u ('appendable_panel' ) : 'AppendablePanelTable' ,
@@ -913,7 +915,14 @@ def error(t):
913
915
# if we are a writer, determin the tt
914
916
if value is not None :
915
917
916
- if pt == u ('frame_table' ):
918
+ if pt == u ('series_table' ):
919
+ index = getattr (value ,'index' ,None )
920
+ if index is not None :
921
+ if index .nlevels == 1 :
922
+ tt = u ('appendable_series' )
923
+ elif index .nlevels > 1 :
924
+ tt = u ('appendable_multiseries' )
925
+ elif pt == u ('frame_table' ):
917
926
index = getattr (value ,'index' ,None )
918
927
if index is not None :
919
928
if index .nlevels == 1 :
@@ -1692,6 +1701,10 @@ def copy(self):
1692
1701
new_self = copy .copy (self )
1693
1702
return new_self
1694
1703
1704
+ @property
1705
+ def storage_obj_type (self ):
1706
+ return self .obj_type
1707
+
1695
1708
@property
1696
1709
def shape (self ):
1697
1710
return self .nrows
@@ -2369,6 +2382,11 @@ def validate(self, other):
2369
2382
# should never get here
2370
2383
raise Exception ("invalid combinate of [%s] on appending data [%s] vs current table [%s]" % (c ,sv ,ov ))
2371
2384
2385
+ @property
2386
+ def is_multi_index (self ):
2387
+ """ the levels attribute is 1 or a list in the case of a multi-index """
2388
+ return isinstance (self .levels ,list )
2389
+
2372
2390
@property
2373
2391
def nrows_expected (self ):
2374
2392
""" based on our axes, compute the expected nrows """
@@ -2419,7 +2437,7 @@ def queryables(self):
2419
2437
2420
2438
# compute the values_axes queryables
2421
2439
return dict ([(a .cname , a .kind ) for a in self .index_axes ] +
2422
- [(self .obj_type ._AXIS_NAMES [axis ], None ) for axis , values in self .non_index_axes ] +
2440
+ [(self .storage_obj_type ._AXIS_NAMES [axis ], None ) for axis , values in self .non_index_axes ] +
2423
2441
[(v .cname , v .kind ) for v in self .values_axes if v .name in set (self .data_columns )]
2424
2442
)
2425
2443
@@ -3277,6 +3295,62 @@ def read(self, where=None, columns=None, **kwargs):
3277
3295
return df
3278
3296
3279
3297
3298
+ class AppendableSeriesTable (AppendableFrameTable ):
3299
+ """ support the new appendable table formats """
3300
+ pandas_kind = u ('series_table' )
3301
+ table_type = u ('appendable_series' )
3302
+ ndim = 2
3303
+ obj_type = Series
3304
+ storage_obj_type = DataFrame
3305
+
3306
+ @property
3307
+ def is_transposed (self ):
3308
+ return False
3309
+
3310
+ def get_object (self , obj ):
3311
+ return obj
3312
+
3313
+ def write (self , obj , data_columns = None , ** kwargs ):
3314
+ """ we are going to write this as a frame table """
3315
+ if not isinstance (obj , DataFrame ):
3316
+ name = obj .name or 'values'
3317
+ obj = DataFrame ({ name : obj }, index = obj .index )
3318
+ obj .columns = [name ]
3319
+ return super (AppendableSeriesTable , self ).write (obj = obj , data_columns = obj .columns , ** kwargs )
3320
+
3321
+ def read (self , columns = None , ** kwargs ):
3322
+
3323
+ is_multi_index = self .is_multi_index
3324
+ if columns is not None and is_multi_index :
3325
+ for n in self .levels :
3326
+ if n not in columns :
3327
+ columns .insert (0 , n )
3328
+ s = super (AppendableSeriesTable , self ).read (columns = columns , ** kwargs )
3329
+ if is_multi_index :
3330
+ s .set_index (self .levels , inplace = True )
3331
+
3332
+ s = s .iloc [:,0 ]
3333
+
3334
+ # remove the default name
3335
+ if s .name == 'values' :
3336
+ s .name = None
3337
+ return s
3338
+
3339
+ class AppendableMultiSeriesTable (AppendableSeriesTable ):
3340
+ """ support the new appendable table formats """
3341
+ pandas_kind = u ('series_table' )
3342
+ table_type = u ('appendable_multiseries' )
3343
+
3344
+ def write (self , obj , ** kwargs ):
3345
+ """ we are going to write this as a frame table """
3346
+ name = obj .name or 'values'
3347
+ cols = list (obj .index .names )
3348
+ cols .append (name )
3349
+ self .levels = list (obj .index .names )
3350
+ obj = obj .reset_index ()
3351
+ obj .columns = cols
3352
+ return super (AppendableMultiSeriesTable , self ).write (obj = obj , ** kwargs )
3353
+
3280
3354
class GenericTable (AppendableFrameTable ):
3281
3355
""" a table that read/writes the generic pytables table format """
3282
3356
pandas_kind = u ('frame_table' )
0 commit comments