Skip to content

Commit 89c5623

Browse files
jbrockmendelPingviinituutti
authored andcommitted
DEPR: Remove Panel-specific parts of io.pytables (pandas-dev#25233)
1 parent 61d6fae commit 89c5623

File tree

6 files changed

+15
-170
lines changed

6 files changed

+15
-170
lines changed

doc/source/whatsnew/v0.25.0.rst

+1-1
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ Deprecations
5151

5252
Removal of prior version deprecations/changes
5353
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
54-
- Removed (parts of) :class:`Panel` (:issue:`25047`)
54+
- Removed (parts of) :class:`Panel` (:issue:`25047`,:issue:`25191`,:issue:`25231`)
5555
-
5656
-
5757
-

pandas/core/internals/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22
from .blocks import ( # noqa:F401
3-
_block2d_to_blocknd, _factor_indexer, _block_shape, # io.pytables
3+
_block_shape, # io.pytables
44
_safe_reshape, # io.packers
55
make_block, # io.pytables, io.packers
66
FloatBlock, IntBlock, ComplexBlock, BoolBlock, ObjectBlock,

pandas/core/internals/blocks.py

-35
Original file line numberDiff line numberDiff line change
@@ -3134,31 +3134,6 @@ def _merge_blocks(blocks, dtype=None, _can_consolidate=True):
31343134
return blocks
31353135

31363136

3137-
def _block2d_to_blocknd(values, placement, shape, labels, ref_items):
3138-
""" pivot to the labels shape """
3139-
panel_shape = (len(placement),) + shape
3140-
3141-
# TODO: lexsort depth needs to be 2!!
3142-
3143-
# Create observation selection vector using major and minor
3144-
# labels, for converting to panel format.
3145-
selector = _factor_indexer(shape[1:], labels)
3146-
mask = np.zeros(np.prod(shape), dtype=bool)
3147-
mask.put(selector, True)
3148-
3149-
if mask.all():
3150-
pvalues = np.empty(panel_shape, dtype=values.dtype)
3151-
else:
3152-
dtype, fill_value = maybe_promote(values.dtype)
3153-
pvalues = np.empty(panel_shape, dtype=dtype)
3154-
pvalues.fill(fill_value)
3155-
3156-
for i in range(len(placement)):
3157-
pvalues[i].flat[mask] = values[:, i]
3158-
3159-
return make_block(pvalues, placement=placement)
3160-
3161-
31623137
def _safe_reshape(arr, new_shape):
31633138
"""
31643139
If possible, reshape `arr` to have shape `new_shape`,
@@ -3181,16 +3156,6 @@ def _safe_reshape(arr, new_shape):
31813156
return arr
31823157

31833158

3184-
def _factor_indexer(shape, labels):
3185-
"""
3186-
given a tuple of shape and a list of Categorical labels, return the
3187-
expanded label indexer
3188-
"""
3189-
mult = np.array(shape)[::-1].cumprod()[::-1]
3190-
return ensure_platform_int(
3191-
np.sum(np.array(labels).T * np.append(mult, [1]), axis=1).T)
3192-
3193-
31943159
def _putmask_smart(v, m, n):
31953160
"""
31963161
Return a new ndarray, try to preserve dtype if possible.

pandas/io/pytables.py

+13-108
Original file line numberDiff line numberDiff line change
@@ -15,34 +15,29 @@
1515

1616
import numpy as np
1717

18-
from pandas._libs import algos, lib, writers as libwriters
18+
from pandas._libs import lib, writers as libwriters
1919
from pandas._libs.tslibs import timezones
2020
from pandas.compat import PY3, filter, lrange, range, string_types
2121
from pandas.errors import PerformanceWarning
2222

2323
from pandas.core.dtypes.common import (
24-
ensure_int64, ensure_object, ensure_platform_int, is_categorical_dtype,
25-
is_datetime64_dtype, is_datetime64tz_dtype, is_list_like,
26-
is_timedelta64_dtype)
24+
ensure_object, is_categorical_dtype, is_datetime64_dtype,
25+
is_datetime64tz_dtype, is_list_like, is_timedelta64_dtype)
2726
from pandas.core.dtypes.missing import array_equivalent
2827

2928
from pandas import (
30-
DataFrame, DatetimeIndex, Index, Int64Index, MultiIndex, Panel,
31-
PeriodIndex, Series, SparseDataFrame, SparseSeries, TimedeltaIndex, compat,
32-
concat, isna, to_datetime)
29+
DataFrame, DatetimeIndex, Index, Int64Index, MultiIndex, PeriodIndex,
30+
Series, SparseDataFrame, SparseSeries, TimedeltaIndex, compat, concat,
31+
isna, to_datetime)
3332
from pandas.core import config
34-
from pandas.core.algorithms import unique
35-
from pandas.core.arrays.categorical import (
36-
Categorical, _factorize_from_iterables)
33+
from pandas.core.arrays.categorical import Categorical
3734
from pandas.core.arrays.sparse import BlockIndex, IntIndex
3835
from pandas.core.base import StringMixin
3936
import pandas.core.common as com
4037
from pandas.core.computation.pytables import Expr, maybe_expression
4138
from pandas.core.config import get_option
4239
from pandas.core.index import ensure_index
43-
from pandas.core.internals import (
44-
BlockManager, _block2d_to_blocknd, _block_shape, _factor_indexer,
45-
make_block)
40+
from pandas.core.internals import BlockManager, _block_shape, make_block
4641

4742
from pandas.io.common import _stringify_path
4843
from pandas.io.formats.printing import adjoin, pprint_thing
@@ -175,7 +170,6 @@ class DuplicateWarning(Warning):
175170
SparseSeries: u'sparse_series',
176171
DataFrame: u'frame',
177172
SparseDataFrame: u'sparse_frame',
178-
Panel: u'wide',
179173
}
180174

181175
# storer class map
@@ -187,7 +181,6 @@ class DuplicateWarning(Warning):
187181
u'sparse_series': 'SparseSeriesFixed',
188182
u'frame': 'FrameFixed',
189183
u'sparse_frame': 'SparseFrameFixed',
190-
u'wide': 'PanelFixed',
191184
}
192185

193186
# table class map
@@ -198,14 +191,11 @@ class DuplicateWarning(Warning):
198191
u'appendable_frame': 'AppendableFrameTable',
199192
u'appendable_multiframe': 'AppendableMultiFrameTable',
200193
u'worm': 'WORMTable',
201-
u'legacy_frame': 'LegacyFrameTable',
202-
u'legacy_panel': 'LegacyPanelTable',
203194
}
204195

205196
# axes map
206197
_AXES_MAP = {
207198
DataFrame: [0],
208-
Panel: [1, 2]
209199
}
210200

211201
# register our configuration options
@@ -864,7 +854,7 @@ def put(self, key, value, format=None, append=False, **kwargs):
864854
Parameters
865855
----------
866856
key : object
867-
value : {Series, DataFrame, Panel}
857+
value : {Series, DataFrame}
868858
format : 'fixed(f)|table(t)', default is 'fixed'
869859
fixed(f) : Fixed format
870860
Fast writing/reading. Not-appendable, nor searchable
@@ -946,7 +936,7 @@ def append(self, key, value, format=None, append=True, columns=None,
946936
Parameters
947937
----------
948938
key : object
949-
value : {Series, DataFrame, Panel}
939+
value : {Series, DataFrame}
950940
format : 'table' is the default
951941
table(t) : table format
952942
Write as a PyTables Table structure which may perform
@@ -3027,16 +3017,6 @@ class FrameFixed(BlockManagerFixed):
30273017
obj_type = DataFrame
30283018

30293019

3030-
class PanelFixed(BlockManagerFixed):
3031-
pandas_kind = u'wide'
3032-
obj_type = Panel
3033-
is_shape_reversed = True
3034-
3035-
def write(self, obj, **kwargs):
3036-
obj._consolidate_inplace()
3037-
return super(PanelFixed, self).write(obj, **kwargs)
3038-
3039-
30403020
class Table(Fixed):
30413021

30423022
""" represent a table:
@@ -3899,85 +3879,11 @@ def read(self, where=None, columns=None, **kwargs):
38993879
if not self.read_axes(where=where, **kwargs):
39003880
return None
39013881

3902-
lst_vals = [a.values for a in self.index_axes]
3903-
labels, levels = _factorize_from_iterables(lst_vals)
3904-
# labels and levels are tuples but lists are expected
3905-
labels = list(labels)
3906-
levels = list(levels)
3907-
N = [len(lvl) for lvl in levels]
3908-
3909-
# compute the key
3910-
key = _factor_indexer(N[1:], labels)
3911-
3912-
objs = []
3913-
if len(unique(key)) == len(key):
3914-
3915-
sorter, _ = algos.groupsort_indexer(
3916-
ensure_int64(key), np.prod(N))
3917-
sorter = ensure_platform_int(sorter)
3918-
3919-
# create the objs
3920-
for c in self.values_axes:
3921-
3922-
# the data need to be sorted
3923-
sorted_values = c.take_data().take(sorter, axis=0)
3924-
if sorted_values.ndim == 1:
3925-
sorted_values = sorted_values.reshape(
3926-
(sorted_values.shape[0], 1))
3927-
3928-
take_labels = [l.take(sorter) for l in labels]
3929-
items = Index(c.values)
3930-
block = _block2d_to_blocknd(
3931-
values=sorted_values, placement=np.arange(len(items)),
3932-
shape=tuple(N), labels=take_labels, ref_items=items)
3933-
3934-
# create the object
3935-
mgr = BlockManager([block], [items] + levels)
3936-
obj = self.obj_type(mgr)
3937-
3938-
# permute if needed
3939-
if self.is_transposed:
3940-
obj = obj.transpose(
3941-
*tuple(Series(self.data_orientation).argsort()))
3942-
3943-
objs.append(obj)
3944-
3945-
else:
3946-
raise NotImplementedError("Panel is removed in pandas 0.25.0")
3947-
3948-
# create the composite object
3949-
if len(objs) == 1:
3950-
wp = objs[0]
3951-
else:
3952-
wp = concat(objs, axis=0, verify_integrity=False)._consolidate()
3953-
3954-
# apply the selection filters & axis orderings
3955-
wp = self.process_axes(wp, columns=columns)
3956-
3957-
return wp
3958-
3959-
3960-
class LegacyFrameTable(LegacyTable):
3961-
3962-
""" support the legacy frame table """
3963-
pandas_kind = u'frame_table'
3964-
table_type = u'legacy_frame'
3965-
obj_type = Panel
3966-
3967-
def read(self, *args, **kwargs):
3968-
return super(LegacyFrameTable, self).read(*args, **kwargs)['value']
3969-
3970-
3971-
class LegacyPanelTable(LegacyTable):
3972-
3973-
""" support the legacy panel table """
3974-
table_type = u'legacy_panel'
3975-
obj_type = Panel
3882+
raise NotImplementedError("Panel is removed in pandas 0.25.0")
39763883

39773884

39783885
class AppendableTable(LegacyTable):
3979-
3980-
""" suppor the new appendable table formats """
3886+
""" support the new appendable table formats """
39813887
_indexables = None
39823888
table_type = u'appendable'
39833889

@@ -4209,8 +4115,7 @@ def delete(self, where=None, start=None, stop=None, **kwargs):
42094115

42104116

42114117
class AppendableFrameTable(AppendableTable):
4212-
4213-
""" suppor the new appendable table formats """
4118+
""" support the new appendable table formats """
42144119
pandas_kind = u'frame_table'
42154120
table_type = u'appendable_frame'
42164121
ndim = 2
-206 KB
Binary file not shown.

pandas/tests/io/test_pytables.py

-25
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,6 @@ def teardown_method(self, method):
141141

142142

143143
@pytest.mark.single
144-
@pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
145144
class TestHDFStore(Base):
146145

147146
def test_format_kwarg_in_constructor(self):
@@ -3984,30 +3983,6 @@ def test_legacy_table_read_py2(self, datapath):
39843983
})
39853984
assert_frame_equal(expected, result)
39863985

3987-
def test_legacy_table_read(self, datapath):
3988-
# legacy table types
3989-
with ensure_clean_store(
3990-
datapath('io', 'data', 'legacy_hdf', 'legacy_table.h5'),
3991-
mode='r') as store:
3992-
3993-
with catch_warnings():
3994-
simplefilter("ignore", pd.io.pytables.IncompatibilityWarning)
3995-
store.select('df1')
3996-
store.select('df2')
3997-
store.select('wp1')
3998-
3999-
# force the frame
4000-
store.select('df2', typ='legacy_frame')
4001-
4002-
# old version warning
4003-
pytest.raises(
4004-
Exception, store.select, 'wp1', 'minor_axis=B')
4005-
4006-
df2 = store.select('df2')
4007-
result = store.select('df2', 'index>df2.index[2]')
4008-
expected = df2[df2.index > df2.index[2]]
4009-
assert_frame_equal(expected, result)
4010-
40113986
def test_copy(self):
40123987

40133988
with catch_warnings(record=True):

0 commit comments

Comments
 (0)