@@ -3145,15 +3145,25 @@ class Table(Fixed):
3145
3145
info : Dict
3146
3146
3147
3147
def __init__ (
3148
- self , parent : HDFStore , group : "Node" , encoding = None , errors : str = "strict"
3148
+ self ,
3149
+ parent : HDFStore ,
3150
+ group : "Node" ,
3151
+ encoding = None ,
3152
+ errors : str = "strict" ,
3153
+ index_axes = None ,
3154
+ non_index_axes = None ,
3155
+ values_axes = None ,
3156
+ data_columns = None ,
3157
+ info = None ,
3158
+ nan_rep = None ,
3149
3159
):
3150
3160
super ().__init__ (parent , group , encoding = encoding , errors = errors )
3151
- self .index_axes = []
3152
- self .non_index_axes = []
3153
- self .values_axes = []
3154
- self .data_columns = []
3155
- self .info = dict ()
3156
- self .nan_rep = None
3161
+ self .index_axes = index_axes or []
3162
+ self .non_index_axes = non_index_axes or []
3163
+ self .values_axes = values_axes or []
3164
+ self .data_columns = data_columns or []
3165
+ self .info = info or dict ()
3166
+ self .nan_rep = nan_rep
3157
3167
3158
3168
@property
3159
3169
def table_type_short (self ) -> str :
@@ -3635,23 +3645,28 @@ def _create_axes(
3635
3645
data_columns = None ,
3636
3646
min_itemsize = None ,
3637
3647
):
3638
- """ create and return the axes
3639
- legacy tables create an indexable column, indexable index,
3640
- non-indexable fields
3641
-
3642
- Parameters
3643
- ----------
3644
- axes: a list of the axes in order to create (names or numbers of
3645
- the axes)
3646
- obj : the object to create axes on
3647
- validate: validate the obj against an existing object already
3648
- written
3649
- min_itemsize: a dict of the min size for a column in bytes
3650
- nan_rep : a values to use for string column nan_rep
3651
- encoding : the encoding for string values
3652
- data_columns : a list of columns that we want to create separate to
3653
- allow indexing (or True will force all columns)
3648
+ """
3649
+ Create and return the axes.
3650
+
3651
+ Parameters
3652
+ ----------
3653
+ axes: list or None
3654
+ The names or numbers of the axes to create.
3655
+ obj : DataFrame
3656
+ The object to create axes on.
3657
+ validate: bool, default True
3658
+ Whether to validate the obj against an existing object already written.
3659
+ nan_rep :
3660
+ A value to use for string column nan_rep.
3661
+ data_columns : List[str], True, or None, default None
3662
+ Specify the columns that we want to create to allow indexing on.
3654
3663
3664
+ * True : Use all available columns.
3665
+ * None : Use no columns.
3666
+ * List[str] : Use the specified columns.
3667
+
3668
+ min_itemsize: Dict[str, int] or None, default None
3669
+ The min itemsize for a column in bytes.
3655
3670
"""
3656
3671
3657
3672
if not isinstance (obj , DataFrame ):
@@ -3670,15 +3685,15 @@ def _create_axes(
3670
3685
3671
3686
# do we have an existing table (if so, use its axes & data_columns)
3672
3687
if self .infer_axes ():
3673
- existing_table = self . copy ()
3688
+ table_exists = True
3674
3689
axes = [a .axis for a in self .index_axes ]
3675
- data_columns = self .data_columns
3690
+ data_columns = list ( self .data_columns )
3676
3691
nan_rep = self .nan_rep
3677
- new_info = self .info
3678
3692
# TODO: do we always have validate=True here?
3679
3693
else :
3680
- existing_table = None
3681
- new_info = self .info
3694
+ table_exists = False
3695
+
3696
+ new_info = self .info
3682
3697
3683
3698
assert self .ndim == 2 # with next check, we must have len(axes) == 1
3684
3699
# currently support on ndim-1 axes
@@ -3700,9 +3715,9 @@ def _create_axes(
3700
3715
a = obj .axes [idx ]
3701
3716
# we might be able to change the axes on the appending data if necessary
3702
3717
append_axis = list (a )
3703
- if existing_table is not None :
3718
+ if table_exists :
3704
3719
indexer = len (new_non_index_axes ) # i.e. 0
3705
- exist_axis = existing_table .non_index_axes [indexer ][1 ]
3720
+ exist_axis = self .non_index_axes [indexer ][1 ]
3706
3721
if not array_equivalent (np .array (append_axis ), np .array (exist_axis )):
3707
3722
3708
3723
# ahah! -> reindex
@@ -3721,8 +3736,8 @@ def _create_axes(
3721
3736
# Now we can construct our new index axis
3722
3737
idx = axes [0 ]
3723
3738
a = obj .axes [idx ]
3724
- index_name = obj ._AXIS_NAMES [idx ]
3725
- new_index = _convert_index (index_name , a , self .encoding , self .errors )
3739
+ axis_name = obj ._AXIS_NAMES [idx ]
3740
+ new_index = _convert_index (axis_name , a , self .encoding , self .errors )
3726
3741
new_index .axis = idx
3727
3742
3728
3743
# Because we are always 2D, there is only one new_index, so
@@ -3749,9 +3764,11 @@ def get_blk_items(mgr, blocks):
3749
3764
data_columns = self .validate_data_columns (
3750
3765
data_columns , min_itemsize , new_non_index_axes
3751
3766
)
3767
+
3752
3768
block_obj = self .get_object (obj , transposed )._consolidate ()
3769
+
3753
3770
blocks , blk_items = self ._get_blocks_and_items (
3754
- block_obj , existing_table , new_non_index_axes , data_columns
3771
+ block_obj , table_exists , new_non_index_axes , self . values_axes , data_columns
3755
3772
)
3756
3773
3757
3774
# add my values
@@ -3772,13 +3789,15 @@ def get_blk_items(mgr, blocks):
3772
3789
3773
3790
# make sure that we match up the existing columns
3774
3791
# if we have an existing table
3775
- if existing_table is not None and validate :
3792
+ existing_col : Optional [DataCol ]
3793
+
3794
+ if table_exists and validate :
3776
3795
try :
3777
- existing_col = existing_table .values_axes [i ]
3796
+ existing_col = self .values_axes [i ]
3778
3797
except (IndexError , KeyError ):
3779
3798
raise ValueError (
3780
3799
f"Incompatible appended table [{ blocks } ]"
3781
- f"with existing table [{ existing_table .values_axes } ]"
3800
+ f"with existing table [{ self .values_axes } ]"
3782
3801
)
3783
3802
else :
3784
3803
existing_col = None
@@ -3827,22 +3846,34 @@ def get_blk_items(mgr, blocks):
3827
3846
3828
3847
j += 1
3829
3848
3830
- self .nan_rep = nan_rep
3831
- self .data_columns = [col .name for col in vaxes if col .is_data_indexable ]
3832
- self .values_axes = vaxes
3833
- self .index_axes = new_index_axes
3834
- self .non_index_axes = new_non_index_axes
3849
+ dcs = [col .name for col in vaxes if col .is_data_indexable ]
3835
3850
3836
- # validate our min_itemsize
3837
- self .validate_min_itemsize (min_itemsize )
3851
+ new_table = type (self )(
3852
+ parent = self .parent ,
3853
+ group = self .group ,
3854
+ encoding = self .encoding ,
3855
+ errors = self .errors ,
3856
+ index_axes = new_index_axes ,
3857
+ non_index_axes = new_non_index_axes ,
3858
+ values_axes = vaxes ,
3859
+ data_columns = dcs ,
3860
+ info = new_info ,
3861
+ nan_rep = nan_rep ,
3862
+ )
3863
+ if hasattr (self , "levels" ):
3864
+ # TODO: get this into constructor, only for appropriate subclass
3865
+ new_table .levels = self .levels
3866
+
3867
+ new_table .validate_min_itemsize (min_itemsize )
3868
+
3869
+ if validate and table_exists :
3870
+ new_table .validate (self )
3838
3871
3839
- # validate the axes if we have an existing table
3840
- if validate :
3841
- self .validate (existing_table )
3872
+ return new_table
3842
3873
3843
3874
@staticmethod
3844
3875
def _get_blocks_and_items (
3845
- block_obj , existing_table , new_non_index_axes , data_columns
3876
+ block_obj , table_exists , new_non_index_axes , values_axes , data_columns
3846
3877
):
3847
3878
# Helper to clarify non-state-altering parts of _create_axes
3848
3879
@@ -3864,15 +3895,15 @@ def get_blk_items(mgr, blocks):
3864
3895
blocks .extend (mgr .blocks )
3865
3896
blk_items .extend (get_blk_items (mgr , mgr .blocks ))
3866
3897
3867
- # reorder the blocks in the same order as the existing_table if we can
3868
- if existing_table is not None :
3898
+ # reorder the blocks in the same order as the existing table if we can
3899
+ if table_exists :
3869
3900
by_items = {
3870
3901
tuple (b_items .tolist ()): (b , b_items )
3871
3902
for b , b_items in zip (blocks , blk_items )
3872
3903
}
3873
3904
new_blocks = []
3874
3905
new_blk_items = []
3875
- for ea in existing_table . values_axes :
3906
+ for ea in values_axes :
3876
3907
items = tuple (ea .values )
3877
3908
try :
3878
3909
b , b_items = by_items .pop (items )
@@ -4103,7 +4134,7 @@ def write(
4103
4134
self ._handle .remove_node (self .group , "table" )
4104
4135
4105
4136
# create the axes
4106
- self ._create_axes (
4137
+ table = self ._create_axes (
4107
4138
axes = axes ,
4108
4139
obj = obj ,
4109
4140
validate = append ,
@@ -4112,34 +4143,34 @@ def write(
4112
4143
data_columns = data_columns ,
4113
4144
)
4114
4145
4115
- for a in self .axes :
4146
+ for a in table .axes :
4116
4147
a .validate_names ()
4117
4148
4118
- if not self .is_exists :
4149
+ if not table .is_exists :
4119
4150
4120
4151
# create the table
4121
- options = self .create_description (
4152
+ options = table .create_description (
4122
4153
complib = complib ,
4123
4154
complevel = complevel ,
4124
4155
fletcher32 = fletcher32 ,
4125
4156
expectedrows = expectedrows ,
4126
4157
)
4127
4158
4128
4159
# set the table attributes
4129
- self .set_attrs ()
4160
+ table .set_attrs ()
4130
4161
4131
4162
# create the table
4132
- self ._handle .create_table (self .group , ** options )
4163
+ table ._handle .create_table (table .group , ** options )
4133
4164
4134
4165
# update my info
4135
- self .attrs .info = self .info
4166
+ table .attrs .info = table .info
4136
4167
4137
4168
# validate the axes and set the kinds
4138
- for a in self .axes :
4139
- a .validate_and_set (self , append )
4169
+ for a in table .axes :
4170
+ a .validate_and_set (table , append )
4140
4171
4141
4172
# add the rows
4142
- self .write_data (chunksize , dropna = dropna )
4173
+ table .write_data (chunksize , dropna = dropna )
4143
4174
4144
4175
def write_data (self , chunksize : Optional [int ], dropna : bool = False ):
4145
4176
""" we form the data into a 2-d including indexes,values,mask
0 commit comments