diff --git a/asv_bench/benchmarks/pandas_vb_common.py b/asv_bench/benchmarks/pandas_vb_common.py index a7e530e7f5ef1..56ccc94c414fb 100644 --- a/asv_bench/benchmarks/pandas_vb_common.py +++ b/asv_bench/benchmarks/pandas_vb_common.py @@ -25,6 +25,11 @@ except: pass +try: + Panel = Panel +except Exception: + Panel = WidePanel + # didn't add to namespace until later try: from pandas.core.index import MultiIndex diff --git a/bench/bench_join_panel.py b/bench/bench_join_panel.py index 113b317dd8ff8..f3c3f8ba15f70 100644 --- a/bench/bench_join_panel.py +++ b/bench/bench_join_panel.py @@ -45,8 +45,8 @@ def reindex_on_axis(panels, axis, axis_reindex): return p -# Does the job but inefficient. It is better to handle -# this like you read a table in pytables. +# does the job but inefficient (better to handle like you read a table in +# pytables...e.g create a LongPanel then convert to Wide) def create_panels_join(cls, panels): """ given an array of panels's, create a single panel """ panels = [a for a in panels if a is not None] diff --git a/doc/source/whatsnew/v0.20.0.txt b/doc/source/whatsnew/v0.20.0.txt index c5bf943cebca7..ca6541256f1d2 100644 --- a/doc/source/whatsnew/v0.20.0.txt +++ b/doc/source/whatsnew/v0.20.0.txt @@ -814,7 +814,6 @@ Removal of prior version deprecations/changes - The ``take_last`` parameter has been dropped from ``duplicated()``, ``drop_duplicates()``, ``nlargest()``, and ``nsmallest()`` methods (:issue:`10236`, :issue:`10792`, :issue:`10920`) - ``Series``, ``Index``, and ``DataFrame`` have dropped the ``sort`` and ``order`` methods (:issue:`10726`) - Where clauses in ``pytables`` are only accepted as strings and expressions types and not other data-types (:issue:`12027`) -- The ``LongPanel`` and ``WidePanel`` classes have been removed (:issue:`10892`) .. _whatsnew_0200.performance: diff --git a/pandas/core/api.py b/pandas/core/api.py index 5018de39ca907..65253dedb8b53 100644 --- a/pandas/core/api.py +++ b/pandas/core/api.py @@ -15,7 +15,7 @@ from pandas.core.series import Series from pandas.core.frame import DataFrame -from pandas.core.panel import Panel +from pandas.core.panel import Panel, WidePanel from pandas.core.panel4d import Panel4D from pandas.core.reshape import (pivot_simple as pivot, get_dummies, lreshape, wide_to_long) diff --git a/pandas/core/panel.py b/pandas/core/panel.py index 50ddc24ac9656..5ab3c44b175fe 100644 --- a/pandas/core/panel.py +++ b/pandas/core/panel.py @@ -4,6 +4,8 @@ # pylint: disable=E1103,W0231,W0212,W0621 from __future__ import division +import warnings + import numpy as np from pandas.types.cast import (infer_dtype_from_scalar, @@ -1554,3 +1556,24 @@ def f(self, other, axis=0): ops.add_special_arithmetic_methods(Panel, **ops.panel_special_funcs) Panel._add_aggregate_operations() Panel._add_numeric_operations() + + +# legacy +class WidePanel(Panel): + + def __init__(self, *args, **kwargs): + # deprecation, #10892 + warnings.warn("WidePanel is deprecated. Please use Panel", + FutureWarning, stacklevel=2) + + super(WidePanel, self).__init__(*args, **kwargs) + + +class LongPanel(DataFrame): + + def __init__(self, *args, **kwargs): + # deprecation, #10892 + warnings.warn("LongPanel is deprecated. Please use DataFrame", + FutureWarning, stacklevel=2) + + super(LongPanel, self).__init__(*args, **kwargs) diff --git a/pandas/tests/api/test_api.py b/pandas/tests/api/test_api.py index 2c7dcf2501f32..73222c246fc70 100644 --- a/pandas/tests/api/test_api.py +++ b/pandas/tests/api/test_api.py @@ -54,7 +54,8 @@ class TestPDApi(Base, tm.TestCase): 'TimedeltaIndex', 'Timestamp'] # these are already deprecated; awaiting removal - deprecated_classes = ['Panel4D', 'SparseList', 'Expr', 'Term'] + deprecated_classes = ['WidePanel', 'Panel4D', + 'SparseList', 'Expr', 'Term'] # these should be deprecated in the future deprecated_classes_in_future = ['Panel'] diff --git a/pandas/tests/io/test_pytables.py b/pandas/tests/io/test_pytables.py index 2d62cb2d6944d..82a98f5d08488 100644 --- a/pandas/tests/io/test_pytables.py +++ b/pandas/tests/io/test_pytables.py @@ -2964,6 +2964,9 @@ def _check(left, right): # empty # self._check_roundtrip(wp.to_frame()[:0], _check) + def test_longpanel(self): + pass + def test_overwrite_node(self): with ensure_clean_store(self.path) as store: diff --git a/pandas/tests/test_panel.py b/pandas/tests/test_panel.py index 13e16f3b90730..ab0322abbcf06 100644 --- a/pandas/tests/test_panel.py +++ b/pandas/tests/test_panel.py @@ -178,6 +178,10 @@ def wrapper(x): class SafeForSparse(object): + @classmethod + def assert_panel_equal(cls, x, y): + assert_panel_equal(x, y) + def test_get_axis(self): assert (self.panel._get_axis(0) is self.panel.items) assert (self.panel._get_axis(1) is self.panel.major_axis) @@ -342,10 +346,10 @@ def check_op(op, name): def test_combinePanel(self): result = self.panel.add(self.panel) - assert_panel_equal(result, self.panel * 2) + self.assert_panel_equal(result, self.panel * 2) def test_neg(self): - assert_panel_equal(-self.panel, self.panel * -1) + self.assert_panel_equal(-self.panel, self.panel * -1) # issue 7692 def test_raise_when_not_implemented(self): @@ -365,22 +369,22 @@ def test_select(self): # select items result = p.select(lambda x: x in ('ItemA', 'ItemC'), axis='items') expected = p.reindex(items=['ItemA', 'ItemC']) - assert_panel_equal(result, expected) + self.assert_panel_equal(result, expected) # select major_axis result = p.select(lambda x: x >= datetime(2000, 1, 15), axis='major') new_major = p.major_axis[p.major_axis >= datetime(2000, 1, 15)] expected = p.reindex(major=new_major) - assert_panel_equal(result, expected) + self.assert_panel_equal(result, expected) # select minor_axis result = p.select(lambda x: x in ('D', 'A'), axis=2) expected = p.reindex(minor=['A', 'D']) - assert_panel_equal(result, expected) + self.assert_panel_equal(result, expected) # corner case, empty thing result = p.select(lambda x: x in ('foo', ), axis='items') - assert_panel_equal(result, p.reindex(items=[])) + self.assert_panel_equal(result, p.reindex(items=[])) def test_get_value(self): for item in self.panel.items: @@ -395,8 +399,8 @@ def test_abs(self): result = self.panel.abs() result2 = abs(self.panel) expected = np.abs(self.panel) - assert_panel_equal(result, expected) - assert_panel_equal(result2, expected) + self.assert_panel_equal(result, expected) + self.assert_panel_equal(result2, expected) df = self.panel['ItemA'] result = df.abs() @@ -863,6 +867,10 @@ def test_set_value(self): class TestPanel(tm.TestCase, PanelTests, CheckIndexing, SafeForLongAndSparse, SafeForSparse): + @classmethod + def assert_panel_equal(cls, x, y): + assert_panel_equal(x, y) + def setUp(self): self.panel = _panel.copy() self.panel.major_axis.name = None @@ -1959,7 +1967,7 @@ def test_round(self): major_axis=pd.date_range('1/1/2000', periods=5), minor_axis=['A', 'B']) result = p.round() - assert_panel_equal(expected, result) + self.assert_panel_equal(expected, result) def test_numpy_round(self): values = [[[-3.2, 2.2], [0, -4.8213], [3.123, 123.12], @@ -1975,7 +1983,7 @@ def test_numpy_round(self): major_axis=pd.date_range('1/1/2000', periods=5), minor_axis=['A', 'B']) result = np.round(p) - assert_panel_equal(expected, result) + self.assert_panel_equal(expected, result) msg = "the 'out' parameter is not supported" tm.assertRaisesRegexp(ValueError, msg, np.round, p, out=p) @@ -2262,12 +2270,15 @@ def test_all_any_unhandled(self): self.assertRaises(NotImplementedError, self.panel.any, bool_only=True) -class TestPanelFrame(tm.TestCase): +class TestLongPanel(tm.TestCase): """ - Check that conversions to and from Panel to DataFrame work. + LongPanel no longer exists, but... """ def setUp(self): + import warnings + warnings.filterwarnings(action='ignore', category=FutureWarning) + panel = tm.makePanel() tm.add_nans(panel) diff --git a/vb_suite/pandas_vb_common.py b/vb_suite/pandas_vb_common.py index 41e43d6ab10e5..bd2e8a1c1d504 100644 --- a/vb_suite/pandas_vb_common.py +++ b/vb_suite/pandas_vb_common.py @@ -18,6 +18,11 @@ except: import pandas._libs.lib as lib +try: + Panel = WidePanel +except Exception: + pass + # didn't add to namespace until later try: from pandas.core.index import MultiIndex