@@ -3205,13 +3205,13 @@ def validate(self, other):
3205
3205
oax = ov [i ]
3206
3206
if sax != oax :
3207
3207
raise ValueError (
3208
- f"invalid combinate of [{ c } ] on appending data "
3208
+ f"invalid combination of [{ c } ] on appending data "
3209
3209
f"[{ sax } ] vs current table [{ oax } ]"
3210
3210
)
3211
3211
3212
3212
# should never get here
3213
3213
raise Exception (
3214
- f"invalid combinate of [{ c } ] on appending data [{ sv } ] vs "
3214
+ f"invalid combination of [{ c } ] on appending data [{ sv } ] vs "
3215
3215
f"current table [{ ov } ]"
3216
3216
)
3217
3217
@@ -3582,7 +3582,8 @@ def _read_axes(
3582
3582
3583
3583
return results
3584
3584
3585
- def get_object (self , obj , transposed : bool ):
3585
+ @classmethod
3586
+ def get_object (cls , obj , transposed : bool ):
3586
3587
""" return the data for this obj """
3587
3588
return obj
3588
3589
@@ -3613,6 +3614,7 @@ def validate_data_columns(self, data_columns, min_itemsize, non_index_axes):
3613
3614
if isinstance (min_itemsize , dict ):
3614
3615
3615
3616
existing_data_columns = set (data_columns )
3617
+ data_columns = list (data_columns ) # ensure we do not modify
3616
3618
data_columns .extend (
3617
3619
[
3618
3620
k
@@ -3624,10 +3626,10 @@ def validate_data_columns(self, data_columns, min_itemsize, non_index_axes):
3624
3626
# return valid columns in the order of our axis
3625
3627
return [c for c in data_columns if c in axis_labels ]
3626
3628
3627
- def create_axes (
3629
+ def _create_axes (
3628
3630
self ,
3629
3631
axes ,
3630
- obj ,
3632
+ obj : DataFrame ,
3631
3633
validate : bool = True ,
3632
3634
nan_rep = None ,
3633
3635
data_columns = None ,
@@ -3652,32 +3654,31 @@ def create_axes(
3652
3654
3653
3655
"""
3654
3656
3657
+ if not isinstance (obj , DataFrame ):
3658
+ group = self .group ._v_name
3659
+ raise TypeError (
3660
+ f"cannot properly create the storer for: [group->{ group } ,"
3661
+ f"value->{ type (obj )} ]"
3662
+ )
3663
+
3655
3664
# set the default axes if needed
3656
3665
if axes is None :
3657
- try :
3658
- axes = _AXES_MAP [type (obj )]
3659
- except KeyError :
3660
- group = self .group ._v_name
3661
- raise TypeError (
3662
- f"cannot properly create the storer for: [group->{ group } ,"
3663
- f"value->{ type (obj )} ]"
3664
- )
3666
+ axes = [0 ]
3665
3667
3666
3668
# map axes to numbers
3667
3669
axes = [obj ._get_axis_number (a ) for a in axes ]
3668
3670
3669
3671
# do we have an existing table (if so, use its axes & data_columns)
3670
3672
if self .infer_axes ():
3671
3673
existing_table = self .copy ()
3672
- existing_table .infer_axes ()
3673
- axes = [a .axis for a in existing_table .index_axes ]
3674
- data_columns = existing_table .data_columns
3675
- nan_rep = existing_table .nan_rep
3676
- self .encoding = existing_table .encoding
3677
- self .errors = existing_table .errors
3678
- self .info = copy .copy (existing_table .info )
3674
+ axes = [a .axis for a in self .index_axes ]
3675
+ data_columns = self .data_columns
3676
+ nan_rep = self .nan_rep
3677
+ new_info = self .info
3678
+ # TODO: do we always have validate=True here?
3679
3679
else :
3680
3680
existing_table = None
3681
+ new_info = self .info
3681
3682
3682
3683
assert self .ndim == 2 # with next check, we must have len(axes) == 1
3683
3684
# currently support on ndim-1 axes
@@ -3693,7 +3694,7 @@ def create_axes(
3693
3694
if nan_rep is None :
3694
3695
nan_rep = "nan"
3695
3696
3696
- # We construct the non-index-axis first, since that alters self.info
3697
+ # We construct the non-index-axis first, since that alters new_info
3697
3698
idx = [x for x in [0 , 1 ] if x not in axes ][0 ]
3698
3699
3699
3700
a = obj .axes [idx ]
@@ -3711,7 +3712,7 @@ def create_axes(
3711
3712
append_axis = exist_axis
3712
3713
3713
3714
# the non_index_axes info
3714
- info = self . info .setdefault (idx , {})
3715
+ info = new_info .setdefault (idx , {})
3715
3716
info ["names" ] = list (a .names )
3716
3717
info ["type" ] = type (a ).__name__
3717
3718
@@ -3720,14 +3721,14 @@ def create_axes(
3720
3721
# Now we can construct our new index axis
3721
3722
idx = axes [0 ]
3722
3723
a = obj .axes [idx ]
3723
- name = obj ._AXIS_NAMES [idx ]
3724
- new_index = _convert_index (name , a , self .encoding , self .errors )
3724
+ index_name = obj ._AXIS_NAMES [idx ]
3725
+ new_index = _convert_index (index_name , a , self .encoding , self .errors )
3725
3726
new_index .axis = idx
3726
3727
3727
3728
# Because we are always 2D, there is only one new_index, so
3728
3729
# we know it will have pos=0
3729
3730
new_index .set_pos (0 )
3730
- new_index .update_info (self . info )
3731
+ new_index .update_info (new_info )
3731
3732
new_index .maybe_set_size (min_itemsize ) # check for column conflicts
3732
3733
3733
3734
new_index_axes = [new_index ]
@@ -3745,47 +3746,13 @@ def get_blk_items(mgr, blocks):
3745
3746
transposed = new_index .axis == 1
3746
3747
3747
3748
# figure out data_columns and get out blocks
3748
- block_obj = self .get_object (obj , transposed )._consolidate ()
3749
- blocks = block_obj ._data .blocks
3750
- blk_items = get_blk_items (block_obj ._data , blocks )
3751
-
3752
3749
data_columns = self .validate_data_columns (
3753
3750
data_columns , min_itemsize , new_non_index_axes
3754
3751
)
3755
- if len (data_columns ):
3756
- axis , axis_labels = new_non_index_axes [0 ]
3757
- new_labels = Index (axis_labels ).difference (Index (data_columns ))
3758
- mgr = block_obj .reindex (new_labels , axis = axis )._data
3759
-
3760
- blocks = list (mgr .blocks )
3761
- blk_items = get_blk_items (mgr , blocks )
3762
- for c in data_columns :
3763
- mgr = block_obj .reindex ([c ], axis = axis )._data
3764
- blocks .extend (mgr .blocks )
3765
- blk_items .extend (get_blk_items (mgr , mgr .blocks ))
3766
-
3767
- # reorder the blocks in the same order as the existing_table if we can
3768
- if existing_table is not None :
3769
- by_items = {
3770
- tuple (b_items .tolist ()): (b , b_items )
3771
- for b , b_items in zip (blocks , blk_items )
3772
- }
3773
- new_blocks = []
3774
- new_blk_items = []
3775
- for ea in existing_table .values_axes :
3776
- items = tuple (ea .values )
3777
- try :
3778
- b , b_items = by_items .pop (items )
3779
- new_blocks .append (b )
3780
- new_blk_items .append (b_items )
3781
- except (IndexError , KeyError ):
3782
- jitems = "," .join (pprint_thing (item ) for item in items )
3783
- raise ValueError (
3784
- f"cannot match existing table structure for [{ jitems } ] "
3785
- "on appending data"
3786
- )
3787
- blocks = new_blocks
3788
- blk_items = new_blk_items
3752
+ block_obj = self .get_object (obj , transposed )._consolidate ()
3753
+ blocks , blk_items = self ._get_blocks_and_items (
3754
+ block_obj , existing_table , new_non_index_axes , data_columns
3755
+ )
3789
3756
3790
3757
# add my values
3791
3758
vaxes = []
@@ -3854,7 +3821,7 @@ def get_blk_items(mgr, blocks):
3854
3821
dtype = dtype_name ,
3855
3822
data = data ,
3856
3823
)
3857
- col .update_info (self . info )
3824
+ col .update_info (new_info )
3858
3825
3859
3826
vaxes .append (col )
3860
3827
@@ -3873,6 +3840,55 @@ def get_blk_items(mgr, blocks):
3873
3840
if validate :
3874
3841
self .validate (existing_table )
3875
3842
3843
+ @staticmethod
3844
+ def _get_blocks_and_items (
3845
+ block_obj , existing_table , new_non_index_axes , data_columns
3846
+ ):
3847
+ # Helper to clarify non-state-altering parts of _create_axes
3848
+
3849
+ def get_blk_items (mgr , blocks ):
3850
+ return [mgr .items .take (blk .mgr_locs ) for blk in blocks ]
3851
+
3852
+ blocks = block_obj ._data .blocks
3853
+ blk_items = get_blk_items (block_obj ._data , blocks )
3854
+
3855
+ if len (data_columns ):
3856
+ axis , axis_labels = new_non_index_axes [0 ]
3857
+ new_labels = Index (axis_labels ).difference (Index (data_columns ))
3858
+ mgr = block_obj .reindex (new_labels , axis = axis )._data
3859
+
3860
+ blocks = list (mgr .blocks )
3861
+ blk_items = get_blk_items (mgr , blocks )
3862
+ for c in data_columns :
3863
+ mgr = block_obj .reindex ([c ], axis = axis )._data
3864
+ blocks .extend (mgr .blocks )
3865
+ blk_items .extend (get_blk_items (mgr , mgr .blocks ))
3866
+
3867
+ # reorder the blocks in the same order as the existing_table if we can
3868
+ if existing_table is not None :
3869
+ by_items = {
3870
+ tuple (b_items .tolist ()): (b , b_items )
3871
+ for b , b_items in zip (blocks , blk_items )
3872
+ }
3873
+ new_blocks = []
3874
+ new_blk_items = []
3875
+ for ea in existing_table .values_axes :
3876
+ items = tuple (ea .values )
3877
+ try :
3878
+ b , b_items = by_items .pop (items )
3879
+ new_blocks .append (b )
3880
+ new_blk_items .append (b_items )
3881
+ except (IndexError , KeyError ):
3882
+ jitems = "," .join (pprint_thing (item ) for item in items )
3883
+ raise ValueError (
3884
+ f"cannot match existing table structure for [{ jitems } ] "
3885
+ "on appending data"
3886
+ )
3887
+ blocks = new_blocks
3888
+ blk_items = new_blk_items
3889
+
3890
+ return blocks , blk_items
3891
+
3876
3892
def process_axes (self , obj , selection : "Selection" , columns = None ):
3877
3893
""" process axes filters """
3878
3894
@@ -4087,7 +4103,7 @@ def write(
4087
4103
self ._handle .remove_node (self .group , "table" )
4088
4104
4089
4105
# create the axes
4090
- self .create_axes (
4106
+ self ._create_axes (
4091
4107
axes = axes ,
4092
4108
obj = obj ,
4093
4109
validate = append ,
@@ -4306,7 +4322,8 @@ class AppendableFrameTable(AppendableTable):
4306
4322
def is_transposed (self ) -> bool :
4307
4323
return self .index_axes [0 ].axis == 1
4308
4324
4309
- def get_object (self , obj , transposed : bool ):
4325
+ @classmethod
4326
+ def get_object (cls , obj , transposed : bool ):
4310
4327
""" these are written transposed """
4311
4328
if transposed :
4312
4329
obj = obj .T
@@ -4405,7 +4422,8 @@ class AppendableSeriesTable(AppendableFrameTable):
4405
4422
def is_transposed (self ) -> bool :
4406
4423
return False
4407
4424
4408
- def get_object (self , obj , transposed : bool ):
4425
+ @classmethod
4426
+ def get_object (cls , obj , transposed : bool ):
4409
4427
return obj
4410
4428
4411
4429
def write (self , obj , data_columns = None , ** kwargs ):
0 commit comments