diff --git a/doc/source/cookbook.rst b/doc/source/cookbook.rst index da54a6a5f5c02..b6690eff89836 100644 --- a/doc/source/cookbook.rst +++ b/doc/source/cookbook.rst @@ -411,16 +411,6 @@ Levels `Flatten Hierarchical columns `__ -panelnd -******* - -The :ref:`panelnd` docs. - -`Construct a 5D panelnd -`__ - -.. _cookbook.missing_data: - Missing Data ------------ diff --git a/doc/source/dsintro.rst b/doc/source/dsintro.rst index 7237dc5f1200b..d7650b6b0938f 100644 --- a/doc/source/dsintro.rst +++ b/doc/source/dsintro.rst @@ -982,21 +982,3 @@ Alternatively, one can convert to an xarray ``DataArray``. p.to_xarray() You can see the full-documentation for the `xarray package `__. - -.. _dsintro.panelnd: -.. _dsintro.panel4d: - -Panel4D and PanelND (Deprecated) --------------------------------- - -.. warning:: - - In 0.19.0 ``Panel4D`` and ``PanelND`` are deprecated and will be removed in - a future version. The recommended way to represent these types of - n-dimensional data are with the - `xarray package `__. - Pandas provides a :meth:`~Panel4D.to_xarray` method to automate - this conversion. - -See the `docs of a previous version `__ -for documentation on these objects. diff --git a/doc/source/whatsnew/v0.23.0.txt b/doc/source/whatsnew/v0.23.0.txt index 6a48abb6c6592..8008d935c30f1 100644 --- a/doc/source/whatsnew/v0.23.0.txt +++ b/doc/source/whatsnew/v0.23.0.txt @@ -249,6 +249,7 @@ Removal of prior version deprecations/changes - The ``Series``, ``Categorical``, and ``Index`` classes have dropped the ``reshape`` method (:issue:`13012`) - ``pandas.tseries.frequencies.get_standard_freq`` has been removed in favor of ``pandas.tseries.frequencies.to_offset(freq).rule_code`` (:issue:`13874`) - The ``freqstr`` keyword has been removed from ``pandas.tseries.frequencies.to_offset`` in favor of ``freq`` (:issue:`13874`) +- The ``Panel4D`` and ``PanelND`` classes have been removed (:issue:`13776`) .. _whatsnew_0230.performance: diff --git a/pandas/core/api.py b/pandas/core/api.py index bff42090d689e..b228a97c99074 100644 --- a/pandas/core/api.py +++ b/pandas/core/api.py @@ -22,7 +22,6 @@ from pandas.core.series import Series from pandas.core.frame import DataFrame from pandas.core.panel import Panel, WidePanel -from pandas.core.panel4d import Panel4D # TODO: Remove import when statsmodels updates #18264 from pandas.core.reshape.reshape import get_dummies diff --git a/pandas/core/dtypes/generic.py b/pandas/core/dtypes/generic.py index 618bcf6495155..629d88aa7f086 100644 --- a/pandas/core/dtypes/generic.py +++ b/pandas/core/dtypes/generic.py @@ -43,7 +43,7 @@ def _check(cls, inst): ABCSeries = create_pandas_abc_type("ABCSeries", "_typ", ("series", )) ABCDataFrame = create_pandas_abc_type("ABCDataFrame", "_typ", ("dataframe", )) -ABCPanel = create_pandas_abc_type("ABCPanel", "_typ", ("panel", "panel4d")) +ABCPanel = create_pandas_abc_type("ABCPanel", "_typ", ("panel",)) ABCSparseSeries = create_pandas_abc_type("ABCSparseSeries", "_subtyp", ('sparse_series', 'sparse_time_series')) diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 84799d12df0c4..1ab7c50d86c98 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -7146,7 +7146,7 @@ def describe(self, percentiles=None, include=None, exclude=None): DataFrame.select_dtypes """ if self.ndim >= 3: - msg = "describe is not implemented on Panel or PanelND objects." + msg = "describe is not implemented on Panel objects." raise NotImplementedError(msg) elif self.ndim == 2 and self.columns.size == 0: raise ValueError("Cannot describe a DataFrame without columns") diff --git a/pandas/core/panel.py b/pandas/core/panel.py index 7ec177b03aeb1..b7111a6d0d5bf 100644 --- a/pandas/core/panel.py +++ b/pandas/core/panel.py @@ -1224,9 +1224,6 @@ def reindex(self, *args, **kwargs): kwargs['minor_axis'] = minor axes = validate_axis_style_args(self, args, kwargs, 'labels', 'reindex') - if self.ndim >= 4: - # Hack for PanelND - axes = {} kwargs.update(axes) kwargs.pop('axis', None) kwargs.pop('labels', None) diff --git a/pandas/core/panel4d.py b/pandas/core/panel4d.py deleted file mode 100644 index 0fac720302cfb..0000000000000 --- a/pandas/core/panel4d.py +++ /dev/null @@ -1,99 +0,0 @@ -""" Panel4D: a 4-d dict like collection of panels """ - -import warnings -from pandas.core.generic import NDFrame -from pandas.core.panelnd import create_nd_panel_factory -from pandas.core.panel import Panel -from pandas.util._validators import validate_axis_style_args - - -Panel4D = create_nd_panel_factory(klass_name='Panel4D', - orders=['labels', 'items', 'major_axis', - 'minor_axis'], - slices={'labels': 'labels', - 'items': 'items', - 'major_axis': 'major_axis', - 'minor_axis': 'minor_axis'}, - slicer=Panel, - aliases={'major': 'major_axis', - 'minor': 'minor_axis'}, stat_axis=2, - ns=dict(__doc__=""" - Panel4D is a 4-Dimensional named container very much like a Panel, but - having 4 named dimensions. It is intended as a test bed for more - N-Dimensional named containers. - - .. deprecated:: 0.19.0 - The recommended way to represent these types of n-dimensional data - are with the `xarray package `__. - Pandas provides a `.to_xarray()` method to automate this conversion. - - Parameters - ---------- - data : ndarray (labels x items x major x minor), or dict of Panels - - labels : Index or array-like : axis=0 - items : Index or array-like : axis=1 - major_axis : Index or array-like: axis=2 - minor_axis : Index or array-like: axis=3 - - dtype : dtype, default None - Data type to force, otherwise infer - copy : boolean, default False - Copy data from inputs. Only affects DataFrame / 2d ndarray input - """)) - - -def panel4d_init(self, data=None, labels=None, items=None, major_axis=None, - minor_axis=None, copy=False, dtype=None): - - # deprecation GH13564 - warnings.warn("\nPanel4D is deprecated and will be removed in a " - "future version.\nThe recommended way to represent " - "these types of n-dimensional data are with\n" - "the `xarray package " - "`__.\n" - "Pandas provides a `.to_xarray()` method to help " - "automate this conversion.\n", - FutureWarning, stacklevel=2) - self._init_data(data=data, labels=labels, items=items, - major_axis=major_axis, minor_axis=minor_axis, copy=copy, - dtype=dtype) - - -def panel4d_reindex(self, labs=None, labels=None, items=None, major_axis=None, - minor_axis=None, axis=None, **kwargs): - # Hack for reindex_axis deprecation - # Ha, we used labels for two different things - # I think this will work still. - if labs is None: - args = () - else: - args = (labs,) - kwargs_ = dict(labels=labels, - items=items, - major_axis=major_axis, - minor_axis=minor_axis, - axis=axis) - kwargs_ = {k: v for k, v in kwargs_.items() if v is not None} - # major = kwargs.pop("major", None) - # minor = kwargs.pop('minor', None) - - # if major is not None: - # if kwargs.get("major_axis"): - # raise TypeError("Cannot specify both 'major' and 'major_axis'") - # kwargs_['major_axis'] = major - # if minor is not None: - # if kwargs.get("minor_axis"): - # raise TypeError("Cannot specify both 'minor' and 'minor_axis'") - # kwargs_['minor_axis'] = minor - - if axis is not None: - kwargs_['axis'] = axis - - axes = validate_axis_style_args(self, args, kwargs_, 'labs', 'reindex') - kwargs.update(axes) - return NDFrame.reindex(self, **kwargs) - - -Panel4D.__init__ = panel4d_init -Panel4D.reindex = panel4d_reindex diff --git a/pandas/core/panelnd.py b/pandas/core/panelnd.py deleted file mode 100644 index 80ee680d2b9d2..0000000000000 --- a/pandas/core/panelnd.py +++ /dev/null @@ -1,132 +0,0 @@ -""" Factory methods to create N-D panels """ - -import warnings -from pandas.compat import zip -import pandas.compat as compat - - -def create_nd_panel_factory(klass_name, orders, slices, slicer, aliases=None, - stat_axis=2, info_axis=0, ns=None): - """ manufacture a n-d class: - - .. deprecated:: 0.19.0 - The recommended way to represent these types of n-dimensional data - are with the `xarray package `__. - Pandas provides a `.to_xarray()` method to automate this conversion. - - Parameters - ---------- - klass_name : the klass name - orders : the names of the axes in order (highest to lowest) - slices : a dictionary that defines how the axes map to the slice axis - slicer : the class representing a slice of this panel - aliases : a dictionary defining aliases for various axes - default = { major : major_axis, minor : minor_axis } - stat_axis : the default statistic axis default = 2 - info_axis : the info axis - - Returns - ------- - a class object representing this panel - """ - - # if slicer is a name, get the object - if isinstance(slicer, compat.string_types): - import pandas - try: - slicer = getattr(pandas, slicer) - except: - raise Exception("cannot create this slicer [%s]" % slicer) - - # build the klass - ns = {} if not ns else ns - klass = type(klass_name, (slicer, ), ns) - - # setup the axes - klass._setup_axes(axes=orders, info_axis=info_axis, stat_axis=stat_axis, - aliases=aliases, slicers=slices) - - klass._constructor_sliced = slicer - - # define the methods #### - def __init__(self, *args, **kwargs): - - # deprecation GH13564 - warnings.warn("\n{klass} is deprecated and will be removed in a " - "future version.\nThe recommended way to represent " - "these types of n-dimensional data are with the\n" - "`xarray package " - "`__.\n" - "Pandas provides a `.to_xarray()` method to help " - "automate this conversion.\n".format( - klass=self.__class__.__name__), - FutureWarning, stacklevel=2) - - if not (kwargs.get('data') or len(args)): - raise Exception("must supply at least a data argument to [%s]" % - klass_name) - if 'copy' not in kwargs: - kwargs['copy'] = False - if 'dtype' not in kwargs: - kwargs['dtype'] = None - self._init_data(*args, **kwargs) - - klass.__init__ = __init__ - - def _get_plane_axes_index(self, axis): - """ return the sliced index for this object """ - - # TODO: axis_name is not used, remove? - axis_name = self._get_axis_name(axis) # noqa - index = self._AXIS_ORDERS.index(axis) - - planes = [] - if index: - planes.extend(self._AXIS_ORDERS[0:index]) - if index != self._AXIS_LEN: - planes.extend(self._AXIS_ORDERS[index + 1:]) - - return planes - - klass._get_plane_axes_index = _get_plane_axes_index - - def _combine(self, other, func, axis=0): - if isinstance(other, klass): - return self._combine_with_constructor(other, func) - return super(klass, self)._combine(other, func, axis=axis) - - klass._combine = _combine - - def _combine_with_constructor(self, other, func): - - # combine labels to form new axes - new_axes = [] - for a in self._AXIS_ORDERS: - new_axes.append(getattr(self, a).union(getattr(other, a))) - - # reindex: could check that everything's the same size, but forget it - d = {a: ax for a, ax in zip(self._AXIS_ORDERS, new_axes)} - d['copy'] = False - this = self.reindex(**d) - other = other.reindex(**d) - - result_values = func(this.values, other.values) - - return self._constructor(result_values, **d) - - klass._combine_with_constructor = _combine_with_constructor - - # set as NonImplemented operations which we don't support - for f in ['to_frame', 'to_excel', 'to_sparse', 'groupby', 'join', 'filter', - 'dropna', 'shift']: - - def func(self, *args, **kwargs): - raise NotImplementedError("this operation is not supported") - - setattr(klass, f, func) - - # add the aggregate operations - klass._add_aggregate_operations() - klass._add_numeric_operations() - - return klass diff --git a/pandas/io/pytables.py b/pandas/io/pytables.py index efe6ab6c18868..72543bb6f825e 100644 --- a/pandas/io/pytables.py +++ b/pandas/io/pytables.py @@ -24,7 +24,7 @@ from pandas.core.dtypes.missing import array_equivalent import numpy as np -from pandas import (Series, DataFrame, Panel, Panel4D, Index, +from pandas import (Series, DataFrame, Panel, Index, MultiIndex, Int64Index, isna, concat, to_datetime, SparseSeries, SparseDataFrame, PeriodIndex, DatetimeIndex, TimedeltaIndex) @@ -180,7 +180,6 @@ class DuplicateWarning(Warning): DataFrame: u('frame'), SparseDataFrame: u('sparse_frame'), Panel: u('wide'), - Panel4D: u('ndim'), } # storer class map @@ -203,7 +202,6 @@ class DuplicateWarning(Warning): u('appendable_frame'): 'AppendableFrameTable', u('appendable_multiframe'): 'AppendableMultiFrameTable', u('appendable_panel'): 'AppendablePanelTable', - u('appendable_ndim'): 'AppendableNDimTable', u('worm'): 'WORMTable', u('legacy_frame'): 'LegacyFrameTable', u('legacy_panel'): 'LegacyPanelTable', @@ -212,8 +210,7 @@ class DuplicateWarning(Warning): # axes map _AXES_MAP = { DataFrame: [0], - Panel: [1, 2], - Panel4D: [1, 2, 3], + Panel: [1, 2] } # register our configuration options @@ -924,7 +921,7 @@ def append(self, key, value, format=None, append=True, columns=None, Parameters ---------- key : object - value : {Series, DataFrame, Panel, Panel4D} + value : {Series, DataFrame, Panel} format: 'table' is the default table(t) : table format Write as a PyTables Table structure which may perform @@ -4346,14 +4343,6 @@ def is_transposed(self): return self.data_orientation != tuple(range(self.ndim)) -class AppendableNDimTable(AppendablePanelTable): - - """ suppor the new appendable table formats """ - table_type = u('appendable_ndim') - ndim = 4 - obj_type = Panel4D - - def _reindex_axis(obj, axis, labels, other=None): ax = obj._get_axis(axis) labels = _ensure_index(labels) diff --git a/pandas/tests/api/test_api.py b/pandas/tests/api/test_api.py index e47f1919faaf5..8962eb90be828 100644 --- a/pandas/tests/api/test_api.py +++ b/pandas/tests/api/test_api.py @@ -51,8 +51,7 @@ class TestPDApi(Base): 'TimedeltaIndex', 'Timestamp', 'Interval', 'IntervalIndex'] # these are already deprecated; awaiting removal - deprecated_classes = ['WidePanel', 'Panel4D', 'TimeGrouper', - 'Expr', 'Term'] + deprecated_classes = ['WidePanel', 'TimeGrouper', 'Expr', 'Term'] # these should be deprecated in the future deprecated_classes_in_future = ['Panel'] diff --git a/pandas/tests/dtypes/test_missing.py b/pandas/tests/dtypes/test_missing.py index fd2c63ef5b37e..4f208bc352c70 100644 --- a/pandas/tests/dtypes/test_missing.py +++ b/pandas/tests/dtypes/test_missing.py @@ -99,13 +99,6 @@ def test_isna_isnull(self, isna_f): expected = p.apply(isna_f) tm.assert_panel_equal(result, expected) - # panel 4d - with catch_warnings(record=True): - for p in [tm.makePanel4D(), tm.add_nans_panel4d(tm.makePanel4D())]: - result = isna_f(p) - expected = p.apply(isna_f) - tm.assert_panel4d_equal(result, expected) - def test_isna_lists(self): result = isna([[False]]) exp = np.array([[False]]) diff --git a/pandas/tests/frame/test_query_eval.py b/pandas/tests/frame/test_query_eval.py index 55aeaf6e77be1..a226f8de3c8bd 100644 --- a/pandas/tests/frame/test_query_eval.py +++ b/pandas/tests/frame/test_query_eval.py @@ -366,12 +366,6 @@ def test_raise_on_panel_with_multiindex(self, parser, engine): with pytest.raises(NotImplementedError): pd.eval('p + 1', parser=parser, engine=engine) - def test_raise_on_panel4d_with_multiindex(self, parser, engine): - p4d = tm.makePanel4D(7) - p4d.items = tm.makeCustomIndex(len(p4d.items), nlevels=2) - with pytest.raises(NotImplementedError): - pd.eval('p4d + 1', parser=parser, engine=engine) - @td.skip_if_no_ne class TestDataFrameQueryNumExprPandas(object): diff --git a/pandas/tests/generic/test_generic.py b/pandas/tests/generic/test_generic.py index a37c1649e5677..3868bdf7d4620 100644 --- a/pandas/tests/generic/test_generic.py +++ b/pandas/tests/generic/test_generic.py @@ -10,8 +10,7 @@ from pandas.core.dtypes.common import is_scalar from pandas import (Series, DataFrame, Panel, - date_range, Panel4D, - MultiIndex) + date_range, MultiIndex) import pandas.io.formats.printing as printing @@ -726,9 +725,6 @@ def test_squeeze(self): with catch_warnings(record=True): for p in [tm.makePanel()]: tm.assert_panel_equal(p.squeeze(), p) - with catch_warnings(record=True): - for p4d in [tm.makePanel4D()]: - tm.assert_panel4d_equal(p4d.squeeze(), p4d) # squeezing df = tm.makeTimeDataFrame().reindex(columns=['A']) @@ -741,14 +737,6 @@ def test_squeeze(self): p = tm.makePanel().reindex(items=['ItemA'], minor_axis=['A']) tm.assert_series_equal(p.squeeze(), p.loc['ItemA', :, 'A']) - with catch_warnings(record=True): - p4d = tm.makePanel4D().reindex(labels=['label1']) - tm.assert_panel_equal(p4d.squeeze(), p4d['label1']) - - with catch_warnings(record=True): - p4d = tm.makePanel4D().reindex(labels=['label1'], items=['ItemA']) - tm.assert_frame_equal(p4d.squeeze(), p4d.loc['label1', 'ItemA']) - # don't fail with 0 length dimensions GH11229 & GH8999 empty_series = Series([], name='five') empty_frame = DataFrame([empty_series]) @@ -796,13 +784,6 @@ def test_transpose(self): tm.assert_raises_regex(TypeError, msg, p.transpose, 2, 0, 1, axes=(2, 0, 1)) - with catch_warnings(record=True): - for p4d in [tm.makePanel4D()]: - tm.assert_panel4d_equal(p4d.transpose(2, 0, 3, 1) - .transpose(1, 3, 0, 2), p4d) - tm.assert_raises_regex(TypeError, msg, p4d.transpose, - 2, 0, 3, 1, axes=(2, 0, 3, 1)) - def test_numpy_transpose(self): msg = "the 'axes' parameter is not supported" @@ -824,12 +805,6 @@ def test_numpy_transpose(self): np.transpose(p, axes=(2, 0, 1)), axes=(1, 2, 0)), p) - with catch_warnings(record=True): - p4d = tm.makePanel4D() - tm.assert_panel4d_equal(np.transpose( - np.transpose(p4d, axes=(2, 0, 3, 1)), - axes=(1, 3, 0, 2)), p4d) - def test_take(self): indices = [1, 5, -2, 6, 3, -1] for s in [tm.makeFloatSeries(), tm.makeStringSeries(), @@ -855,16 +830,6 @@ def test_take(self): minor_axis=p.minor_axis) tm.assert_panel_equal(out, expected) - with catch_warnings(record=True): - for p4d in [tm.makePanel4D()]: - out = p4d.take(indices) - expected = Panel4D(data=p4d.values.take(indices, axis=0), - labels=p4d.labels.take(indices), - major_axis=p4d.major_axis, - minor_axis=p4d.minor_axis, - items=p4d.items) - tm.assert_panel4d_equal(out, expected) - def test_take_invalid_kwargs(self): indices = [-3, 2, 0, 1] s = tm.makeFloatSeries() @@ -872,9 +837,8 @@ def test_take_invalid_kwargs(self): with catch_warnings(record=True): p = tm.makePanel() - p4d = tm.makePanel4D() - for obj in (s, df, p, p4d): + for obj in (s, df, p): msg = r"take\(\) got an unexpected keyword argument 'foo'" tm.assert_raises_regex(TypeError, msg, obj.take, indices, foo=2) diff --git a/pandas/tests/generic/test_panel.py b/pandas/tests/generic/test_panel.py index 1c8be94d6eac3..720f471a0ebd4 100644 --- a/pandas/tests/generic/test_panel.py +++ b/pandas/tests/generic/test_panel.py @@ -3,11 +3,8 @@ from warnings import catch_warnings -import pytest - -from pandas import Panel, Panel4D +from pandas import Panel from pandas.util.testing import (assert_panel_equal, - assert_panel4d_equal, assert_almost_equal) import pandas.util.testing as tm @@ -35,61 +32,3 @@ def test_to_xarray(self): # idempotency assert_panel_equal(result.to_pandas(), p) - - -class TestPanel4D(Generic): - _typ = Panel4D - _comparator = lambda self, x, y: assert_panel4d_equal(x, y, by_blocks=True) - - def test_sample(self): - pytest.skip("sample on Panel4D") - - @td.skip_if_no('xarray', min_version='0.7.0') - def test_to_xarray(self): - from xarray import DataArray - - with catch_warnings(record=True): - p = tm.makePanel4D() - - result = p.to_xarray() - assert isinstance(result, DataArray) - assert len(result.coords) == 4 - assert_almost_equal(list(result.coords.keys()), - ['labels', 'items', 'major_axis', - 'minor_axis']) - assert len(result.dims) == 4 - - # non-convertible - pytest.raises(ValueError, lambda: result.to_pandas()) - - -# run all the tests, but wrap each in a warning catcher -for t in ['test_rename', 'test_get_numeric_data', - 'test_get_default', 'test_nonzero', - 'test_downcast', 'test_constructor_compound_dtypes', - 'test_head_tail', - 'test_size_compat', 'test_split_compat', - 'test_unexpected_keyword', - 'test_stat_unexpected_keyword', 'test_api_compat', - 'test_stat_non_defaults_args', - 'test_truncate_out_of_bounds', - 'test_metadata_propagation', 'test_copy_and_deepcopy', - 'test_sample']: - - def f(): - def tester(self): - f = getattr(super(TestPanel, self), t) - with catch_warnings(record=True): - f() - return tester - - setattr(TestPanel, t, f()) - - def f(): - def tester(self): - f = getattr(super(TestPanel4D, self), t) - with catch_warnings(record=True): - f() - return tester - - setattr(TestPanel4D, t, f()) diff --git a/pandas/tests/io/test_pytables.py b/pandas/tests/io/test_pytables.py index b40350ada546c..04da6da74059b 100644 --- a/pandas/tests/io/test_pytables.py +++ b/pandas/tests/io/test_pytables.py @@ -11,15 +11,14 @@ import numpy as np import pandas as pd -from pandas import (Series, DataFrame, Panel, Panel4D, MultiIndex, Int64Index, +from pandas import (Series, DataFrame, Panel, MultiIndex, Int64Index, RangeIndex, Categorical, bdate_range, date_range, timedelta_range, Index, DatetimeIndex, isna, compat, concat, Timestamp) import pandas.util.testing as tm import pandas.util._test_decorators as td -from pandas.util.testing import (assert_panel4d_equal, - assert_panel_equal, +from pandas.util.testing import (assert_panel_equal, assert_frame_equal, assert_series_equal, set_timezone) @@ -888,30 +887,6 @@ def test_append(self): store.append('wp1', wp.iloc[:, 10:, :]) assert_panel_equal(store['wp1'], wp) - # ndim - p4d = tm.makePanel4D() - _maybe_remove(store, 'p4d') - store.append('p4d', p4d.iloc[:, :, :10, :]) - store.append('p4d', p4d.iloc[:, :, 10:, :]) - assert_panel4d_equal(store['p4d'], p4d) - - # test using axis labels - _maybe_remove(store, 'p4d') - store.append('p4d', p4d.iloc[:, :, :10, :], axes=[ - 'items', 'major_axis', 'minor_axis']) - store.append('p4d', p4d.iloc[:, :, 10:, :], axes=[ - 'items', 'major_axis', 'minor_axis']) - assert_panel4d_equal(store['p4d'], p4d) - - # test using different number of items on each axis - p4d2 = p4d.copy() - p4d2['l4'] = p4d['l1'] - p4d2['l5'] = p4d['l1'] - _maybe_remove(store, 'p4d2') - store.append( - 'p4d2', p4d2, axes=['items', 'major_axis', 'minor_axis']) - assert_panel4d_equal(store['p4d2'], p4d2) - # test using differt order of items on the non-index axes _maybe_remove(store, 'wp1') wp_append1 = wp.iloc[:, :10, :] @@ -1308,76 +1283,6 @@ def test_append_with_different_block_ordering(self): df['float_3'] = Series([1.] * len(df), dtype='float64') pytest.raises(ValueError, store.append, 'df', df) - def test_ndim_indexables(self): - # test using ndim tables in new ways - - with catch_warnings(record=True): - with ensure_clean_store(self.path) as store: - - p4d = tm.makePanel4D() - - def check_indexers(key, indexers): - for i, idx in enumerate(indexers): - descr = getattr(store.root, key).table.description - assert getattr(descr, idx)._v_pos == i - - # append then change (will take existing schema) - indexers = ['items', 'major_axis', 'minor_axis'] - - _maybe_remove(store, 'p4d') - store.append('p4d', p4d.iloc[:, :, :10, :], axes=indexers) - store.append('p4d', p4d.iloc[:, :, 10:, :]) - assert_panel4d_equal(store.select('p4d'), p4d) - check_indexers('p4d', indexers) - - # same as above, but try to append with different axes - _maybe_remove(store, 'p4d') - store.append('p4d', p4d.iloc[:, :, :10, :], axes=indexers) - store.append('p4d', p4d.iloc[:, :, 10:, :], axes=[ - 'labels', 'items', 'major_axis']) - assert_panel4d_equal(store.select('p4d'), p4d) - check_indexers('p4d', indexers) - - # pass incorrect number of axes - _maybe_remove(store, 'p4d') - pytest.raises(ValueError, store.append, 'p4d', p4d.iloc[ - :, :, :10, :], axes=['major_axis', 'minor_axis']) - - # different than default indexables #1 - indexers = ['labels', 'major_axis', 'minor_axis'] - _maybe_remove(store, 'p4d') - store.append('p4d', p4d.iloc[:, :, :10, :], axes=indexers) - store.append('p4d', p4d.iloc[:, :, 10:, :]) - assert_panel4d_equal(store['p4d'], p4d) - check_indexers('p4d', indexers) - - # different than default indexables #2 - indexers = ['major_axis', 'labels', 'minor_axis'] - _maybe_remove(store, 'p4d') - store.append('p4d', p4d.iloc[:, :, :10, :], axes=indexers) - store.append('p4d', p4d.iloc[:, :, 10:, :]) - assert_panel4d_equal(store['p4d'], p4d) - check_indexers('p4d', indexers) - - # partial selection - result = store.select('p4d', ['labels=l1']) - expected = p4d.reindex(labels=['l1']) - assert_panel4d_equal(result, expected) - - # partial selection2 - result = store.select( - 'p4d', "labels='l1' and items='ItemA' and minor_axis='B'") - expected = p4d.reindex( - labels=['l1'], items=['ItemA'], minor_axis=['B']) - assert_panel4d_equal(result, expected) - - # non-existent partial selection - result = store.select( - 'p4d', "labels='l1' and items='Item1' and minor_axis='B'") - expected = p4d.reindex(labels=['l1'], items=[], - minor_axis=['B']) - assert_panel4d_equal(result, expected) - def test_append_with_strings(self): with ensure_clean_store(self.path) as store: @@ -1972,27 +1877,14 @@ def test_pass_spec_to_storer(self): def test_append_misc(self): with ensure_clean_store(self.path) as store: + df = tm.makeDataFrame() + store.append('df', df, chunksize=1) + result = store.select('df') + tm.assert_frame_equal(result, df) - with catch_warnings(record=True): - - # unsupported data types for non-tables - p4d = tm.makePanel4D() - pytest.raises(TypeError, store.put, 'p4d', p4d) - - # unsupported data types - pytest.raises(TypeError, store.put, 'abc', None) - pytest.raises(TypeError, store.put, 'abc', '123') - pytest.raises(TypeError, store.put, 'abc', 123) - pytest.raises(TypeError, store.put, 'abc', np.arange(5)) - - df = tm.makeDataFrame() - store.append('df', df, chunksize=1) - result = store.select('df') - tm.assert_frame_equal(result, df) - - store.append('df1', df, expectedrows=10) - result = store.select('df1') - tm.assert_frame_equal(result, df) + store.append('df1', df, expectedrows=10) + result = store.select('df1') + tm.assert_frame_equal(result, df) # more chunksize in append tests def check(obj, comparator): @@ -2015,10 +1907,6 @@ def check(obj, comparator): p = tm.makePanel() check(p, assert_panel_equal) - with catch_warnings(record=True): - p4d = tm.makePanel4D() - check(p4d, assert_panel4d_equal) - # empty frame, GH4273 with ensure_clean_store(self.path) as store: @@ -2189,21 +2077,6 @@ def test_table_mixed_dtypes(self): store.append('p1_mixed', wp) assert_panel_equal(store.select('p1_mixed'), wp) - with catch_warnings(record=True): - # ndim - wp = tm.makePanel4D() - wp['obj1'] = 'foo' - wp['obj2'] = 'bar' - wp['bool1'] = wp['l1'] > 0 - wp['bool2'] = wp['l2'] > 0 - wp['int1'] = 1 - wp['int2'] = 2 - wp = wp._consolidate() - - with ensure_clean_store(self.path) as store: - store.append('p4d_mixed', wp) - assert_panel4d_equal(store.select('p4d_mixed'), wp) - def test_unimplemented_dtypes_table_columns(self): with ensure_clean_store(self.path) as store: @@ -2545,10 +2418,8 @@ def test_invalid_terms(self): df.loc[0:4, 'string'] = 'bar' wp = tm.makePanel() - p4d = tm.makePanel4D() store.put('df', df, format='table') store.put('wp', wp, format='table') - store.put('p4d', p4d, format='table') # some invalid terms pytest.raises(ValueError, store.select, @@ -2597,8 +2468,7 @@ def test_terms(self): wpneg = Panel.fromDict({-1: tm.makeDataFrame(), 0: tm.makeDataFrame(), 1: tm.makeDataFrame()}) - p4d = tm.makePanel4D() - store.put('p4d', p4d, format='table') + store.put('wp', wp, format='table') store.put('wpneg', wpneg, format='table') @@ -2618,17 +2488,6 @@ def test_terms(self): after='20000108').reindex(minor=['A', 'B']) tm.assert_panel_equal(result, expected) - # p4d - with catch_warnings(record=True): - - result = store.select('p4d', - ("major_axis<'20000108' and " - "minor_axis=['A', 'B'] and " - "items=['ItemA', 'ItemB']")) - expected = p4d.truncate(after='20000108').reindex( - minor=['A', 'B'], items=['ItemA', 'ItemB']) - assert_panel4d_equal(result, expected) - with catch_warnings(record=True): # valid terms @@ -2648,12 +2507,6 @@ def test_terms(self): for t in terms: store.select('wp', t) - store.select('p4d', t) - - # valid for p4d only - terms = ["labels=['l1', 'l2']"] - for t in terms: - store.select('p4d', t) with tm.assert_raises_regex( TypeError, 'Only named functions are supported'): @@ -5353,11 +5206,9 @@ def test_complex_across_dimensions(self): with catch_warnings(record=True): p = Panel({'One': df, 'Two': df}) - p4d = Panel4D({'i': p, 'ii': p}) - objs = [df, p, p4d] - comps = [tm.assert_frame_equal, tm.assert_panel_equal, - tm.assert_panel4d_equal] + objs = [df, p] + comps = [tm.assert_frame_equal, tm.assert_panel_equal] for obj, comp in zip(objs, comps): with ensure_clean_path(self.path) as path: obj.to_hdf(path, 'obj', format='table') diff --git a/pandas/tests/reshape/test_concat.py b/pandas/tests/reshape/test_concat.py index f66cb12b11210..85e3115e96f83 100644 --- a/pandas/tests/reshape/test_concat.py +++ b/pandas/tests/reshape/test_concat.py @@ -1402,39 +1402,6 @@ def df(): # it works! concat([panel1, panel3], axis=1, verify_integrity=True) - def test_panel4d_concat(self): - with catch_warnings(record=True): - p4d = tm.makePanel4D() - - p1 = p4d.iloc[:, :, :5, :] - p2 = p4d.iloc[:, :, 5:, :] - - result = concat([p1, p2], axis=2) - tm.assert_panel4d_equal(result, p4d) - - p1 = p4d.iloc[:, :, :, :2] - p2 = p4d.iloc[:, :, :, 2:] - - result = concat([p1, p2], axis=3) - tm.assert_panel4d_equal(result, p4d) - - def test_panel4d_concat_mixed_type(self): - with catch_warnings(record=True): - p4d = tm.makePanel4D() - - # if things are a bit misbehaved - p1 = p4d.iloc[:, :2, :, :2] - p2 = p4d.iloc[:, :, :, 2:] - p1['L5'] = 'baz' - - result = concat([p1, p2], axis=3) - - p2['L5'] = np.nan - expected = concat([p1, p2], axis=3) - expected = expected.loc[result.labels] - - tm.assert_panel4d_equal(result, expected) - def test_concat_series(self): ts = tm.makeTimeSeries() diff --git a/pandas/tests/test_expressions.py b/pandas/tests/test_expressions.py index aebc9cd3deaac..56e00fa8af23d 100644 --- a/pandas/tests/test_expressions.py +++ b/pandas/tests/test_expressions.py @@ -15,8 +15,7 @@ from pandas.core.computation import expressions as expr from pandas import compat, _np_version_under1p11, _np_version_under1p13 from pandas.util.testing import (assert_almost_equal, assert_series_equal, - assert_frame_equal, assert_panel_equal, - assert_panel4d_equal) + assert_frame_equal, assert_panel_equal) from pandas.io.formats.printing import pprint_thing import pandas.util.testing as tm @@ -205,12 +204,6 @@ def test_float_arithmetic_series(self): def test_float_panel(self): self.run_panel(_frame2_panel, np.random.randn() + 0.1, binary_comp=0.8) - @pytest.mark.slow - def test_panel4d(self): - with catch_warnings(record=True): - self.run_panel(tm.makePanel4D(), np.random.randn() + 0.5, - assert_func=assert_panel4d_equal, binary_comp=3) - def test_mixed_arithmetic_frame(self): # TODO: FIGURE OUT HOW TO GET IT TO WORK... # can't do arithmetic because comparison methods try to do *entire* diff --git a/pandas/tests/test_panel4d.py b/pandas/tests/test_panel4d.py deleted file mode 100644 index e429403bbc919..0000000000000 --- a/pandas/tests/test_panel4d.py +++ /dev/null @@ -1,944 +0,0 @@ -# -*- coding: utf-8 -*- -from datetime import datetime -from pandas.compat import range, lrange -import operator -import pytest -from warnings import catch_warnings -import numpy as np - -from pandas import Series, Index, isna, notna -from pandas.core.dtypes.common import is_float_dtype -from pandas.core.panel import Panel -from pandas.core.panel4d import Panel4D -from pandas.tseries.offsets import BDay - -from pandas.util.testing import (assert_frame_equal, assert_series_equal, - assert_almost_equal) -import pandas.util.testing as tm -import pandas.util._test_decorators as td - - -def add_nans(panel4d): - for l, label in enumerate(panel4d.labels): - panel = panel4d[label] - tm.add_nans(panel) - - -class SafeForLongAndSparse(object): - - def test_repr(self): - repr(self.panel4d) - - def test_iter(self): - tm.equalContents(list(self.panel4d), self.panel4d.labels) - - def test_count(self): - f = lambda s: notna(s).sum() - self._check_stat_op('count', f, obj=self.panel4d, has_skipna=False) - - def test_sum(self): - self._check_stat_op('sum', np.sum, skipna_alternative=np.nansum) - - def test_mean(self): - self._check_stat_op('mean', np.mean) - - @td.skip_if_no("numpy", min_version="1.10.0") - def test_prod(self): - self._check_stat_op('prod', np.prod, skipna_alternative=np.nanprod) - - def test_median(self): - def wrapper(x): - if isna(x).any(): - return np.nan - return np.median(x) - - self._check_stat_op('median', wrapper) - - def test_min(self): - self._check_stat_op('min', np.min) - - def test_max(self): - self._check_stat_op('max', np.max) - - @td.skip_if_no_scipy - def test_skew(self): - from scipy.stats import skew - - def this_skew(x): - if len(x) < 3: - return np.nan - return skew(x, bias=False) - self._check_stat_op('skew', this_skew) - - # def test_mad(self): - # f = lambda x: np.abs(x - x.mean()).mean() - # self._check_stat_op('mad', f) - - def test_var(self): - def alt(x): - if len(x) < 2: - return np.nan - return np.var(x, ddof=1) - self._check_stat_op('var', alt) - - def test_std(self): - def alt(x): - if len(x) < 2: - return np.nan - return np.std(x, ddof=1) - self._check_stat_op('std', alt) - - def test_sem(self): - def alt(x): - if len(x) < 2: - return np.nan - return np.std(x, ddof=1) / np.sqrt(len(x)) - self._check_stat_op('sem', alt) - - # def test_skew(self): - # from scipy.stats import skew - - # def alt(x): - # if len(x) < 3: - # return np.nan - # return skew(x, bias=False) - - # self._check_stat_op('skew', alt) - - def _check_stat_op(self, name, alternative, obj=None, has_skipna=True, - skipna_alternative=None): - if obj is None: - obj = self.panel4d - - # # set some NAs - # obj.loc[5:10] = np.nan - # obj.loc[15:20, -2:] = np.nan - - f = getattr(obj, name) - - if has_skipna: - - skipna_wrapper = tm._make_skipna_wrapper(alternative, - skipna_alternative) - - def wrapper(x): - return alternative(np.asarray(x)) - - with catch_warnings(record=True): - for i in range(obj.ndim): - result = f(axis=i, skipna=False) - expected = obj.apply(wrapper, axis=i) - tm.assert_panel_equal(result, expected) - else: - skipna_wrapper = alternative - wrapper = alternative - - with catch_warnings(record=True): - for i in range(obj.ndim): - result = f(axis=i) - if name in ['sum', 'prod']: - expected = obj.apply(skipna_wrapper, axis=i) - tm.assert_panel_equal(result, expected) - - pytest.raises(Exception, f, axis=obj.ndim) - - -class SafeForSparse(object): - - def test_get_axis(self): - assert self.panel4d._get_axis(0) is self.panel4d.labels - assert self.panel4d._get_axis(1) is self.panel4d.items - assert self.panel4d._get_axis(2) is self.panel4d.major_axis - assert self.panel4d._get_axis(3) is self.panel4d.minor_axis - - def test_set_axis(self): - with catch_warnings(record=True): - new_labels = Index(np.arange(len(self.panel4d.labels))) - - # TODO: unused? - # new_items = Index(np.arange(len(self.panel4d.items))) - - new_major = Index(np.arange(len(self.panel4d.major_axis))) - new_minor = Index(np.arange(len(self.panel4d.minor_axis))) - - # ensure propagate to potentially prior-cached items too - - # TODO: unused? - # label = self.panel4d['l1'] - - self.panel4d.labels = new_labels - - if hasattr(self.panel4d, '_item_cache'): - assert 'l1' not in self.panel4d._item_cache - assert self.panel4d.labels is new_labels - - self.panel4d.major_axis = new_major - assert self.panel4d[0].major_axis is new_major - assert self.panel4d.major_axis is new_major - - self.panel4d.minor_axis = new_minor - assert self.panel4d[0].minor_axis is new_minor - assert self.panel4d.minor_axis is new_minor - - def test_get_axis_number(self): - assert self.panel4d._get_axis_number('labels') == 0 - assert self.panel4d._get_axis_number('items') == 1 - assert self.panel4d._get_axis_number('major') == 2 - assert self.panel4d._get_axis_number('minor') == 3 - - def test_get_axis_name(self): - assert self.panel4d._get_axis_name(0) == 'labels' - assert self.panel4d._get_axis_name(1) == 'items' - assert self.panel4d._get_axis_name(2) == 'major_axis' - assert self.panel4d._get_axis_name(3) == 'minor_axis' - - def test_arith(self): - with catch_warnings(record=True): - self._test_op(self.panel4d, operator.add) - self._test_op(self.panel4d, operator.sub) - self._test_op(self.panel4d, operator.mul) - self._test_op(self.panel4d, operator.truediv) - self._test_op(self.panel4d, operator.floordiv) - self._test_op(self.panel4d, operator.pow) - - self._test_op(self.panel4d, lambda x, y: y + x) - self._test_op(self.panel4d, lambda x, y: y - x) - self._test_op(self.panel4d, lambda x, y: y * x) - self._test_op(self.panel4d, lambda x, y: y / x) - self._test_op(self.panel4d, lambda x, y: y ** x) - - pytest.raises(Exception, self.panel4d.__add__, - self.panel4d['l1']) - - @staticmethod - def _test_op(panel4d, op): - result = op(panel4d, 1) - tm.assert_panel_equal(result['l1'], op(panel4d['l1'], 1)) - - def test_keys(self): - tm.equalContents(list(self.panel4d.keys()), self.panel4d.labels) - - def test_iteritems(self): - """Test panel4d.iteritems()""" - - assert (len(list(self.panel4d.iteritems())) == - len(self.panel4d.labels)) - - def test_combinePanel4d(self): - with catch_warnings(record=True): - result = self.panel4d.add(self.panel4d) - tm.assert_panel4d_equal(result, self.panel4d * 2) - - def test_neg(self): - with catch_warnings(record=True): - tm.assert_panel4d_equal(-self.panel4d, self.panel4d * -1) - - def test_select(self): - with catch_warnings(record=True): - - p = self.panel4d - - # select labels - result = p.select(lambda x: x in ('l1', 'l3'), axis='labels') - expected = p.reindex(labels=['l1', 'l3']) - tm.assert_panel4d_equal(result, expected) - - # select items - result = p.select(lambda x: x in ('ItemA', 'ItemC'), axis='items') - expected = p.reindex(items=['ItemA', 'ItemC']) - tm.assert_panel4d_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) - tm.assert_panel4d_equal(result, expected) - - # select minor_axis - result = p.select(lambda x: x in ('D', 'A'), axis=3) - expected = p.reindex(minor=['A', 'D']) - tm.assert_panel4d_equal(result, expected) - - # corner case, empty thing - result = p.select(lambda x: x in ('foo',), axis='items') - tm.assert_panel4d_equal(result, p.reindex(items=[])) - - def test_get_value(self): - - for item in self.panel.items: - for mjr in self.panel.major_axis[::2]: - for mnr in self.panel.minor_axis: - result = self.panel.get_value(item, mjr, mnr) - expected = self.panel[item][mnr][mjr] - assert_almost_equal(result, expected) - - def test_abs(self): - - with catch_warnings(record=True): - result = self.panel4d.abs() - expected = np.abs(self.panel4d) - tm.assert_panel4d_equal(result, expected) - - p = self.panel4d['l1'] - result = p.abs() - expected = np.abs(p) - tm.assert_panel_equal(result, expected) - - df = p['ItemA'] - result = df.abs() - expected = np.abs(df) - assert_frame_equal(result, expected) - - -class CheckIndexing(object): - - def test_getitem(self): - pytest.raises(Exception, self.panel4d.__getitem__, 'ItemQ') - - def test_delitem_and_pop(self): - - with catch_warnings(record=True): - expected = self.panel4d['l2'] - result = self.panel4d.pop('l2') - tm.assert_panel_equal(expected, result) - assert 'l2' not in self.panel4d.labels - - del self.panel4d['l3'] - assert 'l3' not in self.panel4d.labels - pytest.raises(Exception, self.panel4d.__delitem__, 'l3') - - values = np.empty((4, 4, 4, 4)) - values[0] = 0 - values[1] = 1 - values[2] = 2 - values[3] = 3 - - panel4d = Panel4D(values, lrange(4), lrange(4), - lrange(4), lrange(4)) - - # did we delete the right row? - panel4dc = panel4d.copy() - del panel4dc[0] - tm.assert_panel_equal(panel4dc[1], panel4d[1]) - tm.assert_panel_equal(panel4dc[2], panel4d[2]) - tm.assert_panel_equal(panel4dc[3], panel4d[3]) - - panel4dc = panel4d.copy() - del panel4dc[1] - tm.assert_panel_equal(panel4dc[0], panel4d[0]) - tm.assert_panel_equal(panel4dc[2], panel4d[2]) - tm.assert_panel_equal(panel4dc[3], panel4d[3]) - - panel4dc = panel4d.copy() - del panel4dc[2] - tm.assert_panel_equal(panel4dc[1], panel4d[1]) - tm.assert_panel_equal(panel4dc[0], panel4d[0]) - tm.assert_panel_equal(panel4dc[3], panel4d[3]) - - panel4dc = panel4d.copy() - del panel4dc[3] - tm.assert_panel_equal(panel4dc[1], panel4d[1]) - tm.assert_panel_equal(panel4dc[2], panel4d[2]) - tm.assert_panel_equal(panel4dc[0], panel4d[0]) - - def test_setitem(self): - with catch_warnings(record=True): - - # Panel - p = Panel(dict( - ItemA=self.panel4d['l1']['ItemA'][2:].filter( - items=['A', 'B']))) - self.panel4d['l4'] = p - self.panel4d['l5'] = p - - p2 = self.panel4d['l4'] - - tm.assert_panel_equal(p, p2.reindex(items=p.items, - major_axis=p.major_axis, - minor_axis=p.minor_axis)) - - # scalar - self.panel4d['lG'] = 1 - self.panel4d['lE'] = True - assert self.panel4d['lG'].values.dtype == np.int64 - assert self.panel4d['lE'].values.dtype == np.bool_ - - # object dtype - self.panel4d['lQ'] = 'foo' - assert self.panel4d['lQ'].values.dtype == np.object_ - - # boolean dtype - self.panel4d['lP'] = self.panel4d['l1'] > 0 - assert self.panel4d['lP'].values.dtype == np.bool_ - - def test_setitem_by_indexer(self): - - with catch_warnings(record=True): - - # Panel - panel4dc = self.panel4d.copy() - p = panel4dc.iloc[0] - - def func(): - self.panel4d.iloc[0] = p - pytest.raises(NotImplementedError, func) - - # DataFrame - panel4dc = self.panel4d.copy() - df = panel4dc.iloc[0, 0] - df.iloc[:] = 1 - panel4dc.iloc[0, 0] = df - assert (panel4dc.iloc[0, 0].values == 1).all() - - # Series - panel4dc = self.panel4d.copy() - s = panel4dc.iloc[0, 0, :, 0] - s.iloc[:] = 1 - panel4dc.iloc[0, 0, :, 0] = s - assert (panel4dc.iloc[0, 0, :, 0].values == 1).all() - - # scalar - panel4dc = self.panel4d.copy() - panel4dc.iloc[0] = 1 - panel4dc.iloc[1] = True - panel4dc.iloc[2] = 'foo' - assert (panel4dc.iloc[0].values == 1).all() - assert panel4dc.iloc[1].values.all() - assert (panel4dc.iloc[2].values == 'foo').all() - - def test_setitem_by_indexer_mixed_type(self): - - with catch_warnings(record=True): - # GH 8702 - self.panel4d['foo'] = 'bar' - - # scalar - panel4dc = self.panel4d.copy() - panel4dc.iloc[0] = 1 - panel4dc.iloc[1] = True - panel4dc.iloc[2] = 'foo' - assert (panel4dc.iloc[0].values == 1).all() - assert panel4dc.iloc[1].values.all() - assert (panel4dc.iloc[2].values == 'foo').all() - - def test_comparisons(self): - with catch_warnings(record=True): - p1 = tm.makePanel4D() - p2 = tm.makePanel4D() - - tp = p1.reindex(labels=p1.labels.tolist() + ['foo']) - p = p1[p1.labels[0]] - - def test_comp(func): - result = func(p1, p2) - tm.assert_numpy_array_equal(result.values, - func(p1.values, p2.values)) - - # versus non-indexed same objs - pytest.raises(Exception, func, p1, tp) - - # versus different objs - pytest.raises(Exception, func, p1, p) - - result3 = func(self.panel4d, 0) - tm.assert_numpy_array_equal(result3.values, - func(self.panel4d.values, 0)) - - with np.errstate(invalid='ignore'): - test_comp(operator.eq) - test_comp(operator.ne) - test_comp(operator.lt) - test_comp(operator.gt) - test_comp(operator.ge) - test_comp(operator.le) - - def test_major_xs(self): - ref = self.panel4d['l1']['ItemA'] - - idx = self.panel4d.major_axis[5] - with catch_warnings(record=True): - xs = self.panel4d.major_xs(idx) - - assert_series_equal(xs['l1'].T['ItemA'], - ref.xs(idx), check_names=False) - - # not contained - idx = self.panel4d.major_axis[0] - BDay() - pytest.raises(Exception, self.panel4d.major_xs, idx) - - def test_major_xs_mixed(self): - self.panel4d['l4'] = 'foo' - with catch_warnings(record=True): - xs = self.panel4d.major_xs(self.panel4d.major_axis[0]) - assert xs['l1']['A'].dtype == np.float64 - assert xs['l4']['A'].dtype == np.object_ - - def test_minor_xs(self): - ref = self.panel4d['l1']['ItemA'] - - with catch_warnings(record=True): - idx = self.panel4d.minor_axis[1] - xs = self.panel4d.minor_xs(idx) - - assert_series_equal(xs['l1'].T['ItemA'], ref[idx], check_names=False) - - # not contained - pytest.raises(Exception, self.panel4d.minor_xs, 'E') - - def test_minor_xs_mixed(self): - self.panel4d['l4'] = 'foo' - - with catch_warnings(record=True): - xs = self.panel4d.minor_xs('D') - assert xs['l1'].T['ItemA'].dtype == np.float64 - assert xs['l4'].T['ItemA'].dtype == np.object_ - - def test_xs(self): - l1 = self.panel4d.xs('l1', axis=0) - expected = self.panel4d['l1'] - tm.assert_panel_equal(l1, expected) - - # View if possible - l1_view = self.panel4d.xs('l1', axis=0) - l1_view.values[:] = np.nan - assert np.isnan(self.panel4d['l1'].values).all() - - # Mixed-type - self.panel4d['strings'] = 'foo' - with catch_warnings(record=True): - result = self.panel4d.xs('D', axis=3) - - assert result._is_copy is not None - - def test_getitem_fancy_labels(self): - with catch_warnings(record=True): - panel4d = self.panel4d - - labels = panel4d.labels[[1, 0]] - items = panel4d.items[[1, 0]] - dates = panel4d.major_axis[::2] - cols = ['D', 'C', 'F'] - - # all 4 specified - tm.assert_panel4d_equal(panel4d.loc[labels, items, dates, cols], - panel4d.reindex(labels=labels, items=items, - major=dates, minor=cols)) - - # 3 specified - tm.assert_panel4d_equal(panel4d.loc[:, items, dates, cols], - panel4d.reindex(items=items, major=dates, - minor=cols)) - - # 2 specified - tm.assert_panel4d_equal(panel4d.loc[:, :, dates, cols], - panel4d.reindex(major=dates, minor=cols)) - - tm.assert_panel4d_equal(panel4d.loc[:, items, :, cols], - panel4d.reindex(items=items, minor=cols)) - - tm.assert_panel4d_equal(panel4d.loc[:, items, dates, :], - panel4d.reindex(items=items, major=dates)) - - # only 1 - tm.assert_panel4d_equal(panel4d.loc[:, items, :, :], - panel4d.reindex(items=items)) - - tm.assert_panel4d_equal(panel4d.loc[:, :, dates, :], - panel4d.reindex(major=dates)) - - tm.assert_panel4d_equal(panel4d.loc[:, :, :, cols], - panel4d.reindex(minor=cols)) - - def test_getitem_fancy_slice(self): - pass - - def test_getitem_fancy_ints(self): - pass - - def test_get_value(self): - for label in self.panel4d.labels: - for item in self.panel4d.items: - for mjr in self.panel4d.major_axis[::2]: - for mnr in self.panel4d.minor_axis: - result = self.panel4d.loc[ - label, item, mjr, mnr] - expected = self.panel4d[label][item][mnr][mjr] - assert_almost_equal(result, expected) - - def test_set_value(self): - - with catch_warnings(record=True): - - for label in self.panel4d.labels: - for item in self.panel4d.items: - for mjr in self.panel4d.major_axis[::2]: - for mnr in self.panel4d.minor_axis: - self.panel4d.set_value(label, item, mjr, mnr, 1.) - tm.assert_almost_equal( - self.panel4d[label][item][mnr][mjr], 1.) - - res3 = self.panel4d.set_value('l4', 'ItemE', 'foobar', 'baz', 5) - assert is_float_dtype(res3['l4'].values) - - # resize - res = self.panel4d.set_value('l4', 'ItemE', 'foo', 'bar', 1.5) - assert isinstance(res, Panel4D) - assert res is not self.panel4d - assert res.get_value('l4', 'ItemE', 'foo', 'bar') == 1.5 - - res3 = self.panel4d.set_value('l4', 'ItemE', 'foobar', 'baz', 5) - assert is_float_dtype(res3['l4'].values) - - -class TestPanel4d(CheckIndexing, SafeForSparse, - SafeForLongAndSparse): - - def setup_method(self, method): - with catch_warnings(record=True): - self.panel4d = tm.makePanel4D(nper=8) - add_nans(self.panel4d) - - def test_constructor(self): - - with catch_warnings(record=True): - panel4d = Panel4D(self.panel4d._data) - assert panel4d._data is self.panel4d._data - - panel4d = Panel4D(self.panel4d._data, copy=True) - assert panel4d._data is not self.panel4d._data - tm.assert_panel4d_equal(panel4d, self.panel4d) - - vals = self.panel4d.values - - # no copy - panel4d = Panel4D(vals) - assert panel4d.values is vals - - # copy - panel4d = Panel4D(vals, copy=True) - assert panel4d.values is not vals - - # GH #8285, test when scalar data is used to construct a Panel4D - # if dtype is not passed, it should be inferred - value_and_dtype = [(1, 'int64'), (3.14, 'float64'), - ('foo', np.object_)] - for (val, dtype) in value_and_dtype: - panel4d = Panel4D(val, labels=range(2), items=range( - 3), major_axis=range(4), minor_axis=range(5)) - vals = np.empty((2, 3, 4, 5), dtype=dtype) - vals.fill(val) - expected = Panel4D(vals, dtype=dtype) - tm.assert_panel4d_equal(panel4d, expected) - - # test the case when dtype is passed - panel4d = Panel4D(1, labels=range(2), items=range( - 3), major_axis=range(4), minor_axis=range(5), dtype='float32') - vals = np.empty((2, 3, 4, 5), dtype='float32') - vals.fill(1) - - expected = Panel4D(vals, dtype='float32') - tm.assert_panel4d_equal(panel4d, expected) - - def test_constructor_cast(self): - with catch_warnings(record=True): - zero_filled = self.panel4d.fillna(0) - - casted = Panel4D(zero_filled._data, dtype=int) - casted2 = Panel4D(zero_filled.values, dtype=int) - - exp_values = zero_filled.values.astype(int) - assert_almost_equal(casted.values, exp_values) - assert_almost_equal(casted2.values, exp_values) - - casted = Panel4D(zero_filled._data, dtype=np.int32) - casted2 = Panel4D(zero_filled.values, dtype=np.int32) - - exp_values = zero_filled.values.astype(np.int32) - assert_almost_equal(casted.values, exp_values) - assert_almost_equal(casted2.values, exp_values) - - # can't cast - data = [[['foo', 'bar', 'baz']]] - pytest.raises(ValueError, Panel, data, dtype=float) - - def test_consolidate(self): - with catch_warnings(record=True): - assert self.panel4d._data.is_consolidated() - - self.panel4d['foo'] = 1. - assert not self.panel4d._data.is_consolidated() - - panel4d = self.panel4d._consolidate() - assert panel4d._data.is_consolidated() - - def test_ctor_dict(self): - with catch_warnings(record=True): - l1 = self.panel4d['l1'] - l2 = self.panel4d['l2'] - - d = {'A': l1, 'B': l2.loc[['ItemB'], :, :]} - panel4d = Panel4D(d) - - tm.assert_panel_equal(panel4d['A'], self.panel4d['l1']) - tm.assert_frame_equal(panel4d.loc['B', 'ItemB', :, :], - self.panel4d.loc['l2', ['ItemB'], - :, :]['ItemB']) - - def test_constructor_dict_mixed(self): - with catch_warnings(record=True): - data = {k: v.values for k, v in self.panel4d.iteritems()} - result = Panel4D(data) - - exp_major = Index(np.arange(len(self.panel4d.major_axis))) - tm.assert_index_equal(result.major_axis, exp_major) - - result = Panel4D(data, - labels=self.panel4d.labels, - items=self.panel4d.items, - major_axis=self.panel4d.major_axis, - minor_axis=self.panel4d.minor_axis) - tm.assert_panel4d_equal(result, self.panel4d) - - data['l2'] = self.panel4d['l2'] - - result = Panel4D(data) - tm.assert_panel4d_equal(result, self.panel4d) - - # corner, blow up - data['l2'] = data['l2']['ItemB'] - pytest.raises(Exception, Panel4D, data) - - data['l2'] = self.panel4d['l2'].values[:, :, :-1] - pytest.raises(Exception, Panel4D, data) - - def test_constructor_resize(self): - with catch_warnings(record=True): - data = self.panel4d._data - labels = self.panel4d.labels[:-1] - items = self.panel4d.items[:-1] - major = self.panel4d.major_axis[:-1] - minor = self.panel4d.minor_axis[:-1] - - result = Panel4D(data, labels=labels, items=items, - major_axis=major, minor_axis=minor) - expected = self.panel4d.reindex( - labels=labels, items=items, major=major, minor=minor) - tm.assert_panel4d_equal(result, expected) - - result = Panel4D(data, items=items, major_axis=major) - expected = self.panel4d.reindex(items=items, major=major) - tm.assert_panel4d_equal(result, expected) - - result = Panel4D(data, items=items) - expected = self.panel4d.reindex(items=items) - tm.assert_panel4d_equal(result, expected) - - result = Panel4D(data, minor_axis=minor) - expected = self.panel4d.reindex(minor=minor) - tm.assert_panel4d_equal(result, expected) - - def test_conform(self): - with catch_warnings(record=True): - - p = self.panel4d['l1'].filter(items=['ItemA', 'ItemB']) - conformed = self.panel4d.conform(p) - - tm.assert_index_equal(conformed.items, self.panel4d.labels) - tm.assert_index_equal(conformed.major_axis, - self.panel4d.major_axis) - tm.assert_index_equal(conformed.minor_axis, - self.panel4d.minor_axis) - - def test_reindex(self): - with catch_warnings(record=True): - ref = self.panel4d['l2'] - - # labels - result = self.panel4d.reindex(labels=['l1', 'l2']) - tm.assert_panel_equal(result['l2'], ref) - - # items - result = self.panel4d.reindex(items=['ItemA', 'ItemB']) - assert_frame_equal(result['l2']['ItemB'], ref['ItemB']) - - # major - new_major = list(self.panel4d.major_axis[:10]) - result = self.panel4d.reindex(major=new_major) - assert_frame_equal( - result['l2']['ItemB'], ref['ItemB'].reindex(index=new_major)) - - # raise exception put both major and major_axis - pytest.raises(Exception, self.panel4d.reindex, - major_axis=new_major, major=new_major) - - # minor - new_minor = list(self.panel4d.minor_axis[:2]) - result = self.panel4d.reindex(minor=new_minor) - assert_frame_equal( - result['l2']['ItemB'], ref['ItemB'].reindex(columns=new_minor)) - - result = self.panel4d.reindex(labels=self.panel4d.labels, - items=self.panel4d.items, - major=self.panel4d.major_axis, - minor=self.panel4d.minor_axis) - - # don't necessarily copy - result = self.panel4d.reindex() - tm.assert_panel4d_equal(result, self.panel4d) - assert result is not self.panel4d - - # with filling - smaller_major = self.panel4d.major_axis[::5] - smaller = self.panel4d.reindex(major=smaller_major) - - larger = smaller.reindex(major=self.panel4d.major_axis, - method='pad') - - tm.assert_panel_equal(larger.loc[:, :, - self.panel4d.major_axis[1], :], - smaller.loc[:, :, smaller_major[0], :]) - - # don't necessarily copy - result = self.panel4d.reindex( - major=self.panel4d.major_axis, copy=False) - tm.assert_panel4d_equal(result, self.panel4d) - assert result is self.panel4d - - def test_not_hashable(self): - with catch_warnings(record=True): - p4D_empty = Panel4D() - pytest.raises(TypeError, hash, p4D_empty) - pytest.raises(TypeError, hash, self.panel4d) - - def test_reindex_like(self): - # reindex_like - with catch_warnings(record=True): - smaller = self.panel4d.reindex(labels=self.panel4d.labels[:-1], - items=self.panel4d.items[:-1], - major=self.panel4d.major_axis[:-1], - minor=self.panel4d.minor_axis[:-1]) - smaller_like = self.panel4d.reindex_like(smaller) - tm.assert_panel4d_equal(smaller, smaller_like) - - def test_sort_index(self): - with catch_warnings(record=True): - import random - - rlabels = list(self.panel4d.labels) - ritems = list(self.panel4d.items) - rmajor = list(self.panel4d.major_axis) - rminor = list(self.panel4d.minor_axis) - random.shuffle(rlabels) - random.shuffle(ritems) - random.shuffle(rmajor) - random.shuffle(rminor) - - random_order = self.panel4d.reindex(labels=rlabels) - sorted_panel4d = random_order.sort_index(axis=0) - tm.assert_panel4d_equal(sorted_panel4d, self.panel4d) - - def test_fillna(self): - - with catch_warnings(record=True): - assert not np.isfinite(self.panel4d.values).all() - filled = self.panel4d.fillna(0) - assert np.isfinite(filled.values).all() - - pytest.raises(NotImplementedError, - self.panel4d.fillna, method='pad') - - def test_swapaxes(self): - with catch_warnings(record=True): - result = self.panel4d.swapaxes('labels', 'items') - assert result.items is self.panel4d.labels - - result = self.panel4d.swapaxes('labels', 'minor') - assert result.labels is self.panel4d.minor_axis - - result = self.panel4d.swapaxes('items', 'minor') - assert result.items is self.panel4d.minor_axis - - result = self.panel4d.swapaxes('items', 'major') - assert result.items is self.panel4d.major_axis - - result = self.panel4d.swapaxes('major', 'minor') - assert result.major_axis is self.panel4d.minor_axis - - # this should also work - result = self.panel4d.swapaxes(0, 1) - assert result.labels is self.panel4d.items - - # this works, but return a copy - result = self.panel4d.swapaxes('items', 'items') - tm.assert_panel4d_equal(self.panel4d, result) - assert id(self.panel4d) != id(result) - - def test_update(self): - - with catch_warnings(record=True): - p4d = Panel4D([[[[1.5, np.nan, 3.], - [1.5, np.nan, 3.], - [1.5, np.nan, 3.], - [1.5, np.nan, 3.]], - [[1.5, np.nan, 3.], - [1.5, np.nan, 3.], - [1.5, np.nan, 3.], - [1.5, np.nan, 3.]]]]) - - other = Panel4D([[[[3.6, 2., np.nan]], - [[np.nan, np.nan, 7]]]]) - - p4d.update(other) - - expected = Panel4D([[[[3.6, 2, 3.], - [1.5, np.nan, 3.], - [1.5, np.nan, 3.], - [1.5, np.nan, 3.]], - [[1.5, np.nan, 7], - [1.5, np.nan, 3.], - [1.5, np.nan, 3.], - [1.5, np.nan, 3.]]]]) - - tm.assert_panel4d_equal(p4d, expected) - - def test_dtypes(self): - - result = self.panel4d.dtypes - expected = Series(np.dtype('float64'), index=self.panel4d.labels) - assert_series_equal(result, expected) - - def test_repr_empty(self): - with catch_warnings(record=True): - empty = Panel4D() - repr(empty) - - def test_rename(self): - with catch_warnings(record=True): - - mapper = {'l1': 'foo', - 'l2': 'bar', - 'l3': 'baz'} - - renamed = self.panel4d.rename_axis(mapper, axis=0) - exp = Index(['foo', 'bar', 'baz']) - tm.assert_index_equal(renamed.labels, exp) - - renamed = self.panel4d.rename_axis(str.lower, axis=3) - exp = Index(['a', 'b', 'c', 'd']) - tm.assert_index_equal(renamed.minor_axis, exp) - - # don't copy - renamed_nocopy = self.panel4d.rename_axis(mapper, - axis=0, - copy=False) - renamed_nocopy['foo'] = 3. - assert (self.panel4d['l1'].values == 3).all() - - def test_get_attr(self): - tm.assert_panel_equal(self.panel4d['l1'], self.panel4d.l1) - - # GH issue 15960 - def test_sort_values(self): - pytest.raises(NotImplementedError, self.panel4d.sort_values) - pytest.raises(NotImplementedError, self.panel4d.sort_values, 'ItemA') diff --git a/pandas/tests/test_panelnd.py b/pandas/tests/test_panelnd.py deleted file mode 100644 index c473e3c09cc74..0000000000000 --- a/pandas/tests/test_panelnd.py +++ /dev/null @@ -1,104 +0,0 @@ -# -*- coding: utf-8 -*- -import pytest - -from warnings import catch_warnings -from pandas.core import panelnd -from pandas.core.panel import Panel - -from pandas.util.testing import assert_panel_equal -import pandas.util.testing as tm - - -class TestPanelnd(object): - - def setup_method(self, method): - pass - - def test_4d_construction(self): - - with catch_warnings(record=True): - - # create a 4D - Panel4D = panelnd.create_nd_panel_factory( - klass_name='Panel4D', - orders=['labels', 'items', 'major_axis', 'minor_axis'], - slices={'items': 'items', 'major_axis': 'major_axis', - 'minor_axis': 'minor_axis'}, - slicer=Panel, - aliases={'major': 'major_axis', 'minor': 'minor_axis'}, - stat_axis=2) - - p4d = Panel4D(dict(L1=tm.makePanel(), L2=tm.makePanel())) # noqa - - def test_4d_construction_alt(self): - - with catch_warnings(record=True): - - # create a 4D - Panel4D = panelnd.create_nd_panel_factory( - klass_name='Panel4D', - orders=['labels', 'items', 'major_axis', 'minor_axis'], - slices={'items': 'items', 'major_axis': 'major_axis', - 'minor_axis': 'minor_axis'}, - slicer='Panel', - aliases={'major': 'major_axis', 'minor': 'minor_axis'}, - stat_axis=2) - - p4d = Panel4D(dict(L1=tm.makePanel(), L2=tm.makePanel())) # noqa - - def test_4d_construction_error(self): - - # create a 4D - pytest.raises(Exception, - panelnd.create_nd_panel_factory, - klass_name='Panel4D', - orders=['labels', 'items', 'major_axis', - 'minor_axis'], - slices={'items': 'items', - 'major_axis': 'major_axis', - 'minor_axis': 'minor_axis'}, - slicer='foo', - aliases={'major': 'major_axis', - 'minor': 'minor_axis'}, - stat_axis=2) - - def test_5d_construction(self): - - with catch_warnings(record=True): - - # create a 4D - Panel4D = panelnd.create_nd_panel_factory( - klass_name='Panel4D', - orders=['labels1', 'items', 'major_axis', 'minor_axis'], - slices={'items': 'items', 'major_axis': 'major_axis', - 'minor_axis': 'minor_axis'}, - slicer=Panel, - aliases={'major': 'major_axis', 'minor': 'minor_axis'}, - stat_axis=2) - - # deprecation GH13564 - p4d = Panel4D(dict(L1=tm.makePanel(), L2=tm.makePanel())) - - # create a 5D - Panel5D = panelnd.create_nd_panel_factory( - klass_name='Panel5D', - orders=['cool1', 'labels1', 'items', 'major_axis', - 'minor_axis'], - slices={'labels1': 'labels1', 'items': 'items', - 'major_axis': 'major_axis', - 'minor_axis': 'minor_axis'}, - slicer=Panel4D, - aliases={'major': 'major_axis', 'minor': 'minor_axis'}, - stat_axis=2) - - # deprecation GH13564 - p5d = Panel5D(dict(C1=p4d)) - - # slice back to 4d - results = p5d.iloc[p5d.cool1.get_loc('C1'), :, :, 0:3, :] - expected = p4d.iloc[:, :, 0:3, :] - assert_panel_equal(results['L1'], expected['L1']) - - # test a transpose - # results = p5d.transpose(1,2,3,4,0) - # expected = diff --git a/pandas/util/testing.py b/pandas/util/testing.py index 8dc0aa1e85ef4..2278d1fe25c7c 100644 --- a/pandas/util/testing.py +++ b/pandas/util/testing.py @@ -42,7 +42,7 @@ from pandas import (bdate_range, CategoricalIndex, Categorical, IntervalIndex, DatetimeIndex, TimedeltaIndex, PeriodIndex, RangeIndex, Index, MultiIndex, - Series, DataFrame, Panel, Panel4D) + Series, DataFrame, Panel) from pandas._libs import testing as _testing from pandas.io.common import urlopen @@ -1333,8 +1333,6 @@ def assert_panelnd_equal(left, right, _panel_frame_equal = partial(assert_frame_equal, check_names=False) assert_panel_equal = partial(assert_panelnd_equal, assert_func=_panel_frame_equal) -assert_panel4d_equal = partial(assert_panelnd_equal, - assert_func=assert_panel_equal) # ----------------------------------------------------------------------------- @@ -1674,13 +1672,6 @@ def makePeriodPanel(nper=None): return Panel.fromDict(data) -def makePanel4D(nper=None): - with warnings.catch_warnings(record=True): - d = dict(l1=makePanel(nper), l2=makePanel(nper), - l3=makePanel(nper)) - return Panel4D(d) - - def makeCustomIndex(nentries, nlevels, prefix='#', names=False, ndupe_l=None, idx_type=None): """Create an index/multindex with given dimensions, levels, names, etc'