Skip to content

Commit 3ece097

Browse files
jbrockmendeljreback
authored andcommitted
REF: remove last major pytables state-altering (#30372)
1 parent e46026f commit 3ece097

File tree

1 file changed

+91
-60
lines changed

1 file changed

+91
-60
lines changed

pandas/io/pytables.py

+91-60
Original file line numberDiff line numberDiff line change
@@ -3145,15 +3145,25 @@ class Table(Fixed):
31453145
info: Dict
31463146

31473147
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,
31493159
):
31503160
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
31573167

31583168
@property
31593169
def table_type_short(self) -> str:
@@ -3635,23 +3645,28 @@ def _create_axes(
36353645
data_columns=None,
36363646
min_itemsize=None,
36373647
):
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.
36543663
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.
36553670
"""
36563671

36573672
if not isinstance(obj, DataFrame):
@@ -3670,15 +3685,15 @@ def _create_axes(
36703685

36713686
# do we have an existing table (if so, use its axes & data_columns)
36723687
if self.infer_axes():
3673-
existing_table = self.copy()
3688+
table_exists = True
36743689
axes = [a.axis for a in self.index_axes]
3675-
data_columns = self.data_columns
3690+
data_columns = list(self.data_columns)
36763691
nan_rep = self.nan_rep
3677-
new_info = self.info
36783692
# TODO: do we always have validate=True here?
36793693
else:
3680-
existing_table = None
3681-
new_info = self.info
3694+
table_exists = False
3695+
3696+
new_info = self.info
36823697

36833698
assert self.ndim == 2 # with next check, we must have len(axes) == 1
36843699
# currently support on ndim-1 axes
@@ -3700,9 +3715,9 @@ def _create_axes(
37003715
a = obj.axes[idx]
37013716
# we might be able to change the axes on the appending data if necessary
37023717
append_axis = list(a)
3703-
if existing_table is not None:
3718+
if table_exists:
37043719
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]
37063721
if not array_equivalent(np.array(append_axis), np.array(exist_axis)):
37073722

37083723
# ahah! -> reindex
@@ -3721,8 +3736,8 @@ def _create_axes(
37213736
# Now we can construct our new index axis
37223737
idx = axes[0]
37233738
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)
37263741
new_index.axis = idx
37273742

37283743
# Because we are always 2D, there is only one new_index, so
@@ -3749,9 +3764,11 @@ def get_blk_items(mgr, blocks):
37493764
data_columns = self.validate_data_columns(
37503765
data_columns, min_itemsize, new_non_index_axes
37513766
)
3767+
37523768
block_obj = self.get_object(obj, transposed)._consolidate()
3769+
37533770
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
37553772
)
37563773

37573774
# add my values
@@ -3772,13 +3789,15 @@ def get_blk_items(mgr, blocks):
37723789

37733790
# make sure that we match up the existing columns
37743791
# 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:
37763795
try:
3777-
existing_col = existing_table.values_axes[i]
3796+
existing_col = self.values_axes[i]
37783797
except (IndexError, KeyError):
37793798
raise ValueError(
37803799
f"Incompatible appended table [{blocks}]"
3781-
f"with existing table [{existing_table.values_axes}]"
3800+
f"with existing table [{self.values_axes}]"
37823801
)
37833802
else:
37843803
existing_col = None
@@ -3827,22 +3846,34 @@ def get_blk_items(mgr, blocks):
38273846

38283847
j += 1
38293848

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]
38353850

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)
38383871

3839-
# validate the axes if we have an existing table
3840-
if validate:
3841-
self.validate(existing_table)
3872+
return new_table
38423873

38433874
@staticmethod
38443875
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
38463877
):
38473878
# Helper to clarify non-state-altering parts of _create_axes
38483879

@@ -3864,15 +3895,15 @@ def get_blk_items(mgr, blocks):
38643895
blocks.extend(mgr.blocks)
38653896
blk_items.extend(get_blk_items(mgr, mgr.blocks))
38663897

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:
38693900
by_items = {
38703901
tuple(b_items.tolist()): (b, b_items)
38713902
for b, b_items in zip(blocks, blk_items)
38723903
}
38733904
new_blocks = []
38743905
new_blk_items = []
3875-
for ea in existing_table.values_axes:
3906+
for ea in values_axes:
38763907
items = tuple(ea.values)
38773908
try:
38783909
b, b_items = by_items.pop(items)
@@ -4103,7 +4134,7 @@ def write(
41034134
self._handle.remove_node(self.group, "table")
41044135

41054136
# create the axes
4106-
self._create_axes(
4137+
table = self._create_axes(
41074138
axes=axes,
41084139
obj=obj,
41094140
validate=append,
@@ -4112,34 +4143,34 @@ def write(
41124143
data_columns=data_columns,
41134144
)
41144145

4115-
for a in self.axes:
4146+
for a in table.axes:
41164147
a.validate_names()
41174148

4118-
if not self.is_exists:
4149+
if not table.is_exists:
41194150

41204151
# create the table
4121-
options = self.create_description(
4152+
options = table.create_description(
41224153
complib=complib,
41234154
complevel=complevel,
41244155
fletcher32=fletcher32,
41254156
expectedrows=expectedrows,
41264157
)
41274158

41284159
# set the table attributes
4129-
self.set_attrs()
4160+
table.set_attrs()
41304161

41314162
# create the table
4132-
self._handle.create_table(self.group, **options)
4163+
table._handle.create_table(table.group, **options)
41334164

41344165
# update my info
4135-
self.attrs.info = self.info
4166+
table.attrs.info = table.info
41364167

41374168
# 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)
41404171

41414172
# add the rows
4142-
self.write_data(chunksize, dropna=dropna)
4173+
table.write_data(chunksize, dropna=dropna)
41434174

41444175
def write_data(self, chunksize: Optional[int], dropna: bool = False):
41454176
""" we form the data into a 2-d including indexes,values,mask

0 commit comments

Comments
 (0)