Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

CLN: Removed SparsePanel #13778

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
92 changes: 0 additions & 92 deletions bench/bench_sparse.py

This file was deleted.

21 changes: 11 additions & 10 deletions doc/source/sparse.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,15 @@
Sparse data structures
**********************

We have implemented "sparse" versions of Series, DataFrame, and Panel. These
are not sparse in the typical "mostly 0". You can view these objects as being
"compressed" where any data matching a specific value (NaN/missing by default,
though any value can be chosen) is omitted. A special ``SparseIndex`` object
tracks where data has been "sparsified". This will make much more sense in an
example. All of the standard pandas data structures have a ``to_sparse``
method:
.. note:: The ``SparsePanel`` class has been removed in 0.19.0

We have implemented "sparse" versions of Series and DataFrame (there used to be
one for Panel but was removed in 0.19.0). These are not sparse in the typical
"mostly 0". You can view these objects as being "compressed" where any data matching
a specific value (NaN/missing by default, though any value can be chosen) is omitted.
A special ``SparseIndex`` object tracks where data has been "sparsified". This will
make much more sense in an example. All of the standard pandas data structures have
a ``to_sparse`` method:

.. ipython:: python

Expand Down Expand Up @@ -77,9 +79,8 @@ distinct from the ``fill_value``:
sparr = pd.SparseArray(arr)
sparr

Like the indexed objects (SparseSeries, SparseDataFrame, SparsePanel), a
``SparseArray`` can be converted back to a regular ndarray by calling
``to_dense``:
Like the indexed objects (SparseSeries, SparseDataFrame), a ``SparseArray``
can be converted back to a regular ndarray by calling ``to_dense``:
Copy link
Contributor

@jreback jreback Jul 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

maybe add a warning note somewhere that SparsePanel was deprecated in 0.19.0

Copy link
Member Author

@gfyoung gfyoung Jul 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You mean "removed in 0.19.0" ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yes


.. ipython:: python

Expand Down
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ API changes
~~~~~~~~~~~


- ``Panel.to_sparse`` will raise a ``NotImplementedError`` exception when called (:issue:`13778`)
- ``Index.reshape`` will raise a ``NotImplementedError`` exception when called (:issue:`12882`)
- Non-convertible dates in an excel date column will be returned without conversion and the column will be ``object`` dtype, rather than raising an exception (:issue:`10001`)
- ``eval``'s upcasting rules for ``float32`` types have been updated to be more consistent with NumPy's rules. New behavior will not upcast to ``float64`` if you multiply a pandas ``float32`` object by a scalar float64. (:issue:`12388`)
Expand Down Expand Up @@ -619,6 +620,7 @@ Deprecations

Removal of prior version deprecations/changes
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
- The ``SparsePanel`` class has been removed (:issue:`13778`)
- The ``pd.sandbox`` module has been removed in favor of the external library ``pandas-qt`` (:issue:`13670`)
- The ``pandas.io.data`` and ``pandas.io.wb`` modules are removed in favor of
the `pandas-datareader package <https://github.com/pydata/pandas-datareader>`__ (:issue:`13724`).
Expand Down
2 changes: 1 addition & 1 deletion pandas/api/tests/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ class TestPDApi(Base, tm.TestCase):
'TimedeltaIndex', 'Timestamp']

# these are already deprecated; awaiting removal
deprecated_classes = ['SparsePanel', 'TimeSeries', 'WidePanel',
deprecated_classes = ['TimeSeries', 'WidePanel',
'SparseTimeSeries', 'Panel4D']

# these should be deperecated in the future
Expand Down
22 changes: 6 additions & 16 deletions pandas/core/panel.py
Original file line number Diff line number Diff line change
Expand Up @@ -393,25 +393,15 @@ def _get_plane_axes(self, axis):

fromDict = from_dict

def to_sparse(self, fill_value=None, kind='block'):
def to_sparse(self, *args, **kwargs):
"""
Convert to SparsePanel

Parameters
----------
fill_value : float, default NaN
kind : {'block', 'integer'}
NOT IMPLEMENTED: do not call this method, as sparsifying is not
supported for Panel objects and will raise an error.

Returns
-------
y : SparseDataFrame
Convert to SparsePanel
"""
from pandas.core.sparse import SparsePanel
frames = dict(self.iteritems())
return SparsePanel(frames, items=self.items,
major_axis=self.major_axis,
minor_axis=self.minor_axis, default_kind=kind,
default_fill_value=fill_value)
raise NotImplementedError("sparsifying is not supported "
"for Panel objects")

def to_excel(self, path, na_rep='', engine=None, **kwargs):
"""
Expand Down
1 change: 0 additions & 1 deletion pandas/core/sparse.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,4 +8,3 @@

from pandas.sparse.series import SparseSeries
from pandas.sparse.frame import SparseDataFrame
from pandas.sparse.panel import SparsePanel
14 changes: 1 addition & 13 deletions pandas/io/packers.py
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
Panel, RangeIndex, PeriodIndex, DatetimeIndex, NaT,
Categorical)
from pandas.tslib import NaTType
from pandas.sparse.api import SparseSeries, SparseDataFrame, SparsePanel
from pandas.sparse.api import SparseSeries, SparseDataFrame
from pandas.sparse.array import BlockIndex, IntIndex
from pandas.core.generic import NDFrame
from pandas.core.common import PerformanceWarning
Expand Down Expand Up @@ -447,18 +447,6 @@ def encode(obj):
# d['data'] = dict([(name, ss)
# for name, ss in compat.iteritems(obj)])
# return d
elif isinstance(obj, SparsePanel):
raise NotImplementedError(
'msgpack sparse frame is not implemented'
)
# d = {'typ': 'sparse_panel',
# 'klass': obj.__class__.__name__,
# 'items': obj.items}
# for f in ['default_fill_value', 'default_kind']:
# d[f] = getattr(obj, f, None)
# d['data'] = dict([(name, df)
# for name, df in compat.iteritems(obj)])
# return d
else:

data = obj._data
Expand Down
37 changes: 1 addition & 36 deletions pandas/io/pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
MultiIndex, Int64Index, isnull)
from pandas.core import config
from pandas.io.common import _stringify_path
from pandas.sparse.api import SparseSeries, SparseDataFrame, SparsePanel
from pandas.sparse.api import SparseSeries, SparseDataFrame
from pandas.sparse.array import BlockIndex, IntIndex
from pandas.tseries.api import PeriodIndex, DatetimeIndex
from pandas.tseries.tdi import TimedeltaIndex
Expand Down Expand Up @@ -169,7 +169,6 @@ class DuplicateWarning(Warning):
SparseDataFrame: u('sparse_frame'),
Panel: u('wide'),
Panel4D: u('ndim'),
SparsePanel: u('sparse_panel')
}

# storer class map
Expand All @@ -183,7 +182,6 @@ class DuplicateWarning(Warning):
u('frame'): 'FrameFixed',
u('sparse_frame'): 'SparseFrameFixed',
u('wide'): 'PanelFixed',
u('sparse_panel'): 'SparsePanelFixed',
}

# table class map
Expand Down Expand Up @@ -2777,39 +2775,6 @@ def write(self, obj, **kwargs):
self.write_index('columns', obj.columns)


class SparsePanelFixed(SparseFixed):
pandas_kind = u('sparse_panel')
attributes = ['default_kind', 'default_fill_value']

def read(self, **kwargs):
kwargs = self.validate_read(kwargs)
items = self.read_index('items')

sdict = {}
for name in items:
key = 'sparse_frame_%s' % name
s = SparseFrameFixed(self.parent, getattr(self.group, key))
s.infer_axes()
sdict[name] = s.read()
return SparsePanel(sdict, items=items, default_kind=self.default_kind,
default_fill_value=self.default_fill_value)

def write(self, obj, **kwargs):
super(SparsePanelFixed, self).write(obj, **kwargs)
self.attrs.default_fill_value = obj.default_fill_value
self.attrs.default_kind = obj.default_kind
self.write_index('items', obj.items)

for name, sdf in obj.iteritems():
key = 'sparse_frame_%s' % name
if key not in self.group._v_children:
node = self._handle.create_group(self.group, key)
else:
node = getattr(self.group, key)
s = SparseFrameFixed(self.parent, node)
s.write(sdf)


class BlockManagerFixed(GenericFixed):
attributes = ['ndim', 'nblocks']
is_shape_reversed = False
Expand Down
20 changes: 0 additions & 20 deletions pandas/io/tests/test_packers.py
Original file line number Diff line number Diff line change
Expand Up @@ -542,26 +542,6 @@ def test_sparse_frame(self):
self._check_roundtrip(ss3, tm.assert_frame_equal,
check_frame_type=True)

def test_sparse_panel(self):

with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):

items = ['x', 'y', 'z']
p = Panel(dict((i, tm.makeDataFrame().ix[:2, :2]) for i in items))
sp = p.to_sparse()

self._check_roundtrip(sp, tm.assert_panel_equal,
check_panel_type=True)

sp2 = p.to_sparse(kind='integer')
self._check_roundtrip(sp2, tm.assert_panel_equal,
check_panel_type=True)

sp3 = p.to_sparse(fill_value=0)
self._check_roundtrip(sp3, tm.assert_panel_equal,
check_panel_type=True)


class TestCompression(TestPackers):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

hmm I think we have legacy pickled / msgpacks that DO serialize this, so need to ignore that NotImplementedError when checking (IOW in io/tests/test_pickle.py)

Copy link
Member Author

@gfyoung gfyoung Jul 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really follow. How are we supposed to test pickling sparse_panel if it doesn't exist? Are we supposed to just check the Panel object itself then?

Copy link
Contributor

@jreback jreback Jul 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

well if u have a class that doesn't exist and you try to unpickle it will fail

now I don't know if these are actually saved in pickles (maybe not) so may be moot

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As I mentioned below, I don't believe that there are any pickles for SparsePanel.

"""See https://github.com/pydata/pandas/pull/9783
Expand Down
17 changes: 0 additions & 17 deletions pandas/io/tests/test_pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -2688,23 +2688,6 @@ def test_sparse_frame(self):
self._check_double_roundtrip(ss3, tm.assert_frame_equal,
check_frame_type=True)

def test_sparse_panel(self):

items = ['x', 'y', 'z']
p = Panel(dict((i, tm.makeDataFrame().ix[:2, :2]) for i in items))
sp = p.to_sparse()

self._check_double_roundtrip(sp, assert_panel_equal,
check_panel_type=True)

sp2 = p.to_sparse(kind='integer')
self._check_double_roundtrip(sp2, assert_panel_equal,
check_panel_type=True)

sp3 = p.to_sparse(fill_value=0)
self._check_double_roundtrip(sp3, assert_panel_equal,
check_panel_type=True)

def test_float_index(self):
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same here, these exist in the legacy file (I think)

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

GitHub search says otherwise. Also, not in the generate_legacy_storage_files.py file.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's possible these were never put there

Copy link
Member Author

@gfyoung gfyoung Jul 24, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Well, unless specific files can be pointed out, a GitHub search is sufficient to convince me that they are not there. Not to mention, there would have been test failures because all legacy pickles should be tested (this was the same issue with the Categorical levels thing).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

no a search is not sufficient
but if we don't have tests which fail when u remove it - it is fine

you always have to assume other people don't do things and test everything


# GH #454
Expand Down
1 change: 0 additions & 1 deletion pandas/sparse/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,3 @@
from pandas.sparse.list import SparseList
from pandas.sparse.series import SparseSeries, SparseTimeSeries
from pandas.sparse.frame import SparseDataFrame
from pandas.sparse.panel import SparsePanel
Loading