Skip to content

Commit 6dc29c5

Browse files
jbrockmendelPingviinituutti
authored andcommitted
DEPR: remove PanelGroupBy, disable DataFrame.to_panel (pandas-dev#25047)
1 parent 24773bd commit 6dc29c5

15 files changed

+14
-541
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-
54+
- Removed (parts of) :class:`Panel` (:issue:`25047`)
5555
-
5656
-
5757
-

pandas/core/frame.py

+1-39
Original file line numberDiff line numberDiff line change
@@ -1974,45 +1974,7 @@ def to_panel(self):
19741974
-------
19751975
panel : Panel
19761976
"""
1977-
# only support this kind for now
1978-
if (not isinstance(self.index, MultiIndex) or # pragma: no cover
1979-
len(self.index.levels) != 2):
1980-
raise NotImplementedError('Only 2-level MultiIndex are supported.')
1981-
1982-
if not self.index.is_unique:
1983-
raise ValueError("Can't convert non-uniquely indexed "
1984-
"DataFrame to Panel")
1985-
1986-
self._consolidate_inplace()
1987-
1988-
# minor axis must be sorted
1989-
if self.index.lexsort_depth < 2:
1990-
selfsorted = self.sort_index(level=0)
1991-
else:
1992-
selfsorted = self
1993-
1994-
major_axis, minor_axis = selfsorted.index.levels
1995-
major_codes, minor_codes = selfsorted.index.codes
1996-
shape = len(major_axis), len(minor_axis)
1997-
1998-
# preserve names, if any
1999-
major_axis = major_axis.copy()
2000-
major_axis.name = self.index.names[0]
2001-
2002-
minor_axis = minor_axis.copy()
2003-
minor_axis.name = self.index.names[1]
2004-
2005-
# create new axes
2006-
new_axes = [selfsorted.columns, major_axis, minor_axis]
2007-
2008-
# create new manager
2009-
new_mgr = selfsorted._data.reshape_nd(axes=new_axes,
2010-
labels=[major_codes,
2011-
minor_codes],
2012-
shape=shape,
2013-
ref_items=selfsorted.columns)
2014-
2015-
return self._constructor_expanddim(new_mgr)
1977+
raise NotImplementedError("Panel is being removed in pandas 0.25.0.")
20161978

20171979
@deprecate_kwarg(old_arg_name='encoding', new_arg_name=None)
20181980
def to_stata(self, fname, convert_dates=None, write_index=True,

pandas/core/groupby/__init__.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
from pandas.core.groupby.groupby import GroupBy # noqa: F401
22
from pandas.core.groupby.generic import ( # noqa: F401
3-
SeriesGroupBy, DataFrameGroupBy, PanelGroupBy)
3+
SeriesGroupBy, DataFrameGroupBy)
44
from pandas.core.groupby.grouper import Grouper # noqa: F401

pandas/core/groupby/generic.py

+1-89
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
"""
2-
Define the SeriesGroupBy, DataFrameGroupBy, and PanelGroupBy
2+
Define the SeriesGroupBy and DataFrameGroupBy
33
classes that hold the groupby interfaces (and some implementations).
44
55
These are user facing as the result of the ``df.groupby(...)`` operations,
@@ -39,7 +39,6 @@
3939
from pandas.core.index import CategoricalIndex, Index, MultiIndex
4040
import pandas.core.indexes.base as ibase
4141
from pandas.core.internals import BlockManager, make_block
42-
from pandas.core.panel import Panel
4342
from pandas.core.series import Series
4443

4544
from pandas.plotting._core import boxplot_frame_groupby
@@ -1586,90 +1585,3 @@ def groupby_series(obj, col=None):
15861585
return results
15871586

15881587
boxplot = boxplot_frame_groupby
1589-
1590-
1591-
class PanelGroupBy(NDFrameGroupBy):
1592-
1593-
def aggregate(self, arg, *args, **kwargs):
1594-
return super(PanelGroupBy, self).aggregate(arg, *args, **kwargs)
1595-
1596-
agg = aggregate
1597-
1598-
def _iterate_slices(self):
1599-
if self.axis == 0:
1600-
# kludge
1601-
if self._selection is None:
1602-
slice_axis = self._selected_obj.items
1603-
else:
1604-
slice_axis = self._selection_list
1605-
slicer = lambda x: self._selected_obj[x]
1606-
else:
1607-
raise NotImplementedError("axis other than 0 is not supported")
1608-
1609-
for val in slice_axis:
1610-
if val in self.exclusions:
1611-
continue
1612-
1613-
yield val, slicer(val)
1614-
1615-
def aggregate(self, arg, *args, **kwargs):
1616-
"""
1617-
Aggregate using input function or dict of {column -> function}
1618-
1619-
Parameters
1620-
----------
1621-
arg : function or dict
1622-
Function to use for aggregating groups. If a function, must either
1623-
work when passed a Panel or when passed to Panel.apply. If
1624-
pass a dict, the keys must be DataFrame column names
1625-
1626-
Returns
1627-
-------
1628-
aggregated : Panel
1629-
"""
1630-
if isinstance(arg, compat.string_types):
1631-
return getattr(self, arg)(*args, **kwargs)
1632-
1633-
return self._aggregate_generic(arg, *args, **kwargs)
1634-
1635-
def _wrap_generic_output(self, result, obj):
1636-
if self.axis == 0:
1637-
new_axes = list(obj.axes)
1638-
new_axes[0] = self.grouper.result_index
1639-
elif self.axis == 1:
1640-
x, y, z = obj.axes
1641-
new_axes = [self.grouper.result_index, z, x]
1642-
else:
1643-
x, y, z = obj.axes
1644-
new_axes = [self.grouper.result_index, y, x]
1645-
1646-
result = Panel._from_axes(result, new_axes)
1647-
1648-
if self.axis == 1:
1649-
result = result.swapaxes(0, 1).swapaxes(0, 2)
1650-
elif self.axis == 2:
1651-
result = result.swapaxes(0, 2)
1652-
1653-
return result
1654-
1655-
def _aggregate_item_by_item(self, func, *args, **kwargs):
1656-
obj = self._obj_with_exclusions
1657-
result = {}
1658-
1659-
if self.axis > 0:
1660-
for item in obj:
1661-
try:
1662-
itemg = DataFrameGroupBy(obj[item],
1663-
axis=self.axis - 1,
1664-
grouper=self.grouper)
1665-
result[item] = itemg.aggregate(func, *args, **kwargs)
1666-
except (ValueError, TypeError):
1667-
raise
1668-
new_axes = list(obj.axes)
1669-
new_axes[self.axis] = self.grouper.result_index
1670-
return Panel._from_axes(result, new_axes)
1671-
else:
1672-
raise ValueError("axis value must be greater than 0")
1673-
1674-
def _wrap_aggregated_output(self, output, names=None):
1675-
raise AbstractMethodError(self)

pandas/core/panel.py

+1-3
Original file line numberDiff line numberDiff line change
@@ -917,9 +917,7 @@ def groupby(self, function, axis='major'):
917917
-------
918918
grouped : PanelGroupBy
919919
"""
920-
from pandas.core.groupby import PanelGroupBy
921-
axis = self._get_axis_number(axis)
922-
return PanelGroupBy(self, function, axis=axis)
920+
raise NotImplementedError("Panel is removed in pandas 0.25.0")
923921

924922
def to_frame(self, filter_observations=True):
925923
"""

pandas/core/resample.py

+2-7
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
import pandas.core.algorithms as algos
2121
from pandas.core.generic import _shared_docs
2222
from pandas.core.groupby.base import GroupByMixin
23-
from pandas.core.groupby.generic import PanelGroupBy, SeriesGroupBy
23+
from pandas.core.groupby.generic import SeriesGroupBy
2424
from pandas.core.groupby.groupby import (
2525
GroupBy, _GroupBy, _pipe_template, groupby)
2626
from pandas.core.groupby.grouper import Grouper
@@ -340,12 +340,7 @@ def _groupby_and_aggregate(self, how, grouper=None, *args, **kwargs):
340340

341341
obj = self._selected_obj
342342

343-
try:
344-
grouped = groupby(obj, by=None, grouper=grouper, axis=self.axis)
345-
except TypeError:
346-
347-
# panel grouper
348-
grouped = PanelGroupBy(obj, grouper=grouper, axis=self.axis)
343+
grouped = groupby(obj, by=None, grouper=grouper, axis=self.axis)
349344

350345
try:
351346
if isinstance(obj, ABCDataFrame) and compat.callable(how):

pandas/io/pytables.py

+2-37
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
PeriodIndex, Series, SparseDataFrame, SparseSeries, TimedeltaIndex, compat,
3232
concat, isna, to_datetime)
3333
from pandas.core import config
34-
from pandas.core.algorithms import match, unique
34+
from pandas.core.algorithms import unique
3535
from pandas.core.arrays.categorical import (
3636
Categorical, _factorize_from_iterables)
3737
from pandas.core.arrays.sparse import BlockIndex, IntIndex
@@ -3944,29 +3944,7 @@ def read(self, where=None, columns=None, **kwargs):
39443944
objs.append(obj)
39453945

39463946
else:
3947-
warnings.warn(duplicate_doc, DuplicateWarning, stacklevel=5)
3948-
3949-
# reconstruct
3950-
long_index = MultiIndex.from_arrays(
3951-
[i.values for i in self.index_axes])
3952-
3953-
for c in self.values_axes:
3954-
lp = DataFrame(c.data, index=long_index, columns=c.values)
3955-
3956-
# need a better algorithm
3957-
tuple_index = long_index.values
3958-
3959-
unique_tuples = unique(tuple_index)
3960-
unique_tuples = com.asarray_tuplesafe(unique_tuples)
3961-
3962-
indexer = match(unique_tuples, tuple_index)
3963-
indexer = ensure_platform_int(indexer)
3964-
3965-
new_index = long_index.take(indexer)
3966-
new_values = lp.values.take(indexer, axis=0)
3967-
3968-
lp = DataFrame(new_values, index=new_index, columns=lp.columns)
3969-
objs.append(lp.to_panel())
3947+
raise NotImplementedError("Panel is removed in pandas 0.25.0")
39703948

39713949
# create the composite object
39723950
if len(objs) == 1:
@@ -4875,16 +4853,3 @@ def select_coords(self):
48754853
return self.coordinates
48764854

48774855
return np.arange(start, stop)
4878-
4879-
# utilities ###
4880-
4881-
4882-
def timeit(key, df, fn=None, remove=True, **kwargs):
4883-
if fn is None:
4884-
fn = 'timeit.h5'
4885-
store = HDFStore(fn, mode='w')
4886-
store.append(key, df, **kwargs)
4887-
store.close()
4888-
4889-
if remove:
4890-
os.remove(fn)

pandas/tests/dtypes/test_generic.py

+1-4
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# -*- coding: utf-8 -*-
22

3-
from warnings import catch_warnings, simplefilter
3+
from warnings import catch_warnings
44

55
import numpy as np
66

@@ -39,9 +39,6 @@ def test_abc_types(self):
3939
assert isinstance(pd.Int64Index([1, 2, 3]), gt.ABCIndexClass)
4040
assert isinstance(pd.Series([1, 2, 3]), gt.ABCSeries)
4141
assert isinstance(self.df, gt.ABCDataFrame)
42-
with catch_warnings(record=True):
43-
simplefilter('ignore', FutureWarning)
44-
assert isinstance(self.df.to_panel(), gt.ABCPanel)
4542
assert isinstance(self.sparse_series, gt.ABCSparseSeries)
4643
assert isinstance(self.sparse_array, gt.ABCSparseArray)
4744
assert isinstance(self.sparse_frame, gt.ABCSparseDataFrame)

pandas/tests/frame/test_subclass.py

+1-24
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
import pytest
77

88
import pandas as pd
9-
from pandas import DataFrame, Index, MultiIndex, Panel, Series
9+
from pandas import DataFrame, Index, MultiIndex, Series
1010
from pandas.tests.frame.common import TestData
1111
import pandas.util.testing as tm
1212

@@ -125,29 +125,6 @@ def test_indexing_sliced(self):
125125
tm.assert_series_equal(res, exp)
126126
assert isinstance(res, tm.SubclassedSeries)
127127

128-
@pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
129-
def test_to_panel_expanddim(self):
130-
# GH 9762
131-
132-
class SubclassedFrame(DataFrame):
133-
134-
@property
135-
def _constructor_expanddim(self):
136-
return SubclassedPanel
137-
138-
class SubclassedPanel(Panel):
139-
pass
140-
141-
index = MultiIndex.from_tuples([(0, 0), (0, 1), (0, 2)])
142-
df = SubclassedFrame({'X': [1, 2, 3], 'Y': [4, 5, 6]}, index=index)
143-
result = df.to_panel()
144-
assert isinstance(result, SubclassedPanel)
145-
expected = SubclassedPanel([[[1, 2, 3]], [[4, 5, 6]]],
146-
items=['X', 'Y'], major_axis=[0],
147-
minor_axis=[0, 1, 2],
148-
dtype='int64')
149-
tm.assert_panel_equal(result, expected)
150-
151128
def test_subclass_attr_err_propagation(self):
152129
# GH 11808
153130
class A(DataFrame):

pandas/tests/groupby/test_groupby.py

-25
Original file line numberDiff line numberDiff line change
@@ -1239,31 +1239,6 @@ def _check_work(gp):
12391239
# _check_work(panel.groupby(lambda x: x.month, axis=1))
12401240

12411241

1242-
@pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
1243-
def test_panel_groupby():
1244-
panel = tm.makePanel()
1245-
tm.add_nans(panel)
1246-
grouped = panel.groupby({'ItemA': 0, 'ItemB': 0, 'ItemC': 1},
1247-
axis='items')
1248-
agged = grouped.mean()
1249-
agged2 = grouped.agg(lambda x: x.mean('items'))
1250-
1251-
tm.assert_panel_equal(agged, agged2)
1252-
1253-
tm.assert_index_equal(agged.items, Index([0, 1]))
1254-
1255-
grouped = panel.groupby(lambda x: x.month, axis='major')
1256-
agged = grouped.mean()
1257-
1258-
exp = Index(sorted(list(set(panel.major_axis.month))))
1259-
tm.assert_index_equal(agged.major_axis, exp)
1260-
1261-
grouped = panel.groupby({'A': 0, 'B': 0, 'C': 1, 'D': 1},
1262-
axis='minor')
1263-
agged = grouped.mean()
1264-
tm.assert_index_equal(agged.minor_axis, Index([0, 1]))
1265-
1266-
12671242
def test_groupby_2d_malformed():
12681243
d = DataFrame(index=lrange(2))
12691244
d['group'] = ['g1', 'g2']

pandas/tests/groupby/test_grouping.py

+1-25
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414
from pandas.core.groupby.grouper import Grouping
1515
import pandas.util.testing as tm
1616
from pandas.util.testing import (
17-
assert_almost_equal, assert_frame_equal, assert_panel_equal,
18-
assert_series_equal)
17+
assert_almost_equal, assert_frame_equal, assert_series_equal)
1918

2019
# selection
2120
# --------------------------------
@@ -563,17 +562,7 @@ def test_list_grouper_with_nat(self):
563562
# --------------------------------
564563

565564
class TestGetGroup():
566-
567-
@pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
568565
def test_get_group(self):
569-
wp = tm.makePanel()
570-
grouped = wp.groupby(lambda x: x.month, axis='major')
571-
572-
gp = grouped.get_group(1)
573-
expected = wp.reindex(
574-
major=[x for x in wp.major_axis if x.month == 1])
575-
assert_panel_equal(gp, expected)
576-
577566
# GH 5267
578567
# be datelike friendly
579568
df = DataFrame({'DATE': pd.to_datetime(
@@ -755,19 +744,6 @@ def test_multi_iter_frame(self, three_group):
755744
for key, group in grouped:
756745
pass
757746

758-
@pytest.mark.filterwarnings("ignore:\\nPanel:FutureWarning")
759-
def test_multi_iter_panel(self):
760-
wp = tm.makePanel()
761-
grouped = wp.groupby([lambda x: x.month, lambda x: x.weekday()],
762-
axis=1)
763-
764-
for (month, wd), group in grouped:
765-
exp_axis = [x
766-
for x in wp.major_axis
767-
if x.month == month and x.weekday() == wd]
768-
expected = wp.reindex(major=exp_axis)
769-
assert_panel_equal(group, expected)
770-
771747
def test_dictify(self, df):
772748
dict(iter(df.groupby('A')))
773749
dict(iter(df.groupby(['A', 'B'])))

0 commit comments

Comments
 (0)