Skip to content

DEPR: Deprecate Series/Dataframe.to_dense/to_sparse #26684

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

Merged
merged 37 commits into from
Jun 19, 2019
Merged
Show file tree
Hide file tree
Changes from 34 commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
a71737c
Deprecate Series/Dataframe.to_dense/to_sparse()
VikramjeetD Jun 5, 2019
fc08e93
Update series.py
VikramjeetD Jun 5, 2019
82c713d
Beautify
VikramjeetD Jun 5, 2019
39230d4
Beautify
VikramjeetD Jun 5, 2019
1e7c0e8
Beautify
VikramjeetD Jun 7, 2019
e68826c
Update Deprecated SparseDF/Series tests
VikramjeetD Jun 7, 2019
20b8962
Beautify
VikramjeetD Jun 8, 2019
50d0534
Deprecate NDFrame.to_dense
VikramjeetD Jun 8, 2019
933162d
Beautify
VikramjeetD Jun 8, 2019
dd1e6c2
Silence test time deprecation warnings
VikramjeetD Jun 8, 2019
c7f27fd
Beautify
VikramjeetD Jun 8, 2019
be14520
Propose changes to certain tests
VikramjeetD Jun 8, 2019
b12e447
Propose changes to tests. IGNORE PREV COMMIT.
VikramjeetD Jun 8, 2019
2d4de51
Silence test time deprecation warnings
VikramjeetD Jun 9, 2019
eede9b8
Add tests for Series/DataFrame.to_sparse
VikramjeetD Jun 9, 2019
0b08795
Beautify
VikramjeetD Jun 9, 2019
5182a1f
Modify test time warning silence
VikramjeetD Jun 12, 2019
15909c5
Modify groupby ops to remove NDFrame test warnings and add wcatch for…
VikramjeetD Jun 17, 2019
104c12a
Remove filterwarning from test_hist_method.py
VikramjeetD Jun 17, 2019
e713fb0
Update sparsearray test_arithmetics warning
VikramjeetD Jun 17, 2019
587b14f
Remove filterwarning from test_decimal.py
VikramjeetD Jun 17, 2019
1318676
Beautify
VikramjeetD Jun 17, 2019
9043e03
Merge branch 'master' of https://github.com/IntEll1gent/pandas
VikramjeetD Jun 17, 2019
58c678a
Beautify
VikramjeetD Jun 17, 2019
ca14ac1
Merge branch 'master' of https://github.com/IntEll1gent/pandas
VikramjeetD Jun 17, 2019
0c8f287
Update test warnings
VikramjeetD Jun 17, 2019
871ccff
Merge remote-tracking branch 'upstream/master'
VikramjeetD Jun 17, 2019
a8f6c56
Update pandas/core/generic.py
VikramjeetD Jun 17, 2019
72aaca5
Merge branch 'master' of https://github.com/IntEll1gent/pandas
VikramjeetD Jun 17, 2019
6a6e333
Update test time warnings and rectify df/series.to_sparse double warn…
VikramjeetD Jun 17, 2019
4e67856
Update more test time warnings
VikramjeetD Jun 17, 2019
4a3181b
Update test warnings
VikramjeetD Jun 17, 2019
a546a89
Update test warnings
VikramjeetD Jun 17, 2019
5fdb2f8
Revert minor changes
VikramjeetD Jun 17, 2019
a627828
Change location of Series/df.test_deprecated_to_sparse
VikramjeetD Jun 18, 2019
3d36430
Remove SDF/SS.to_dense depr:class already deprecated
VikramjeetD Jun 18, 2019
9f888c5
Add whatsnew entry
VikramjeetD Jun 18, 2019
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
13 changes: 10 additions & 3 deletions pandas/core/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -1889,6 +1889,8 @@ def to_sparse(self, fill_value=None, kind='block'):
"""
Convert to SparseDataFrame.

.. deprecated:: 0.25.0

Implement the sparse version of the DataFrame meaning that any data
matching a specific value it's omitted in the representation.
The sparse DataFrame allows for a more efficient storage.
Expand Down Expand Up @@ -1939,10 +1941,15 @@ def to_sparse(self, fill_value=None, kind='block'):
>>> type(sdf) # doctest: +SKIP
<class 'pandas.core.sparse.frame.SparseDataFrame'>
"""
warnings.warn("DataFrame.to_sparse is deprecated and will be removed "
"in a future version", FutureWarning, stacklevel=2)

from pandas.core.sparse.api import SparseDataFrame
return SparseDataFrame(self._series, index=self.index,
columns=self.columns, default_kind=kind,
default_fill_value=fill_value)
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="SparseDataFrame")
return SparseDataFrame(self._series, index=self.index,
columns=self.columns, default_kind=kind,
default_fill_value=fill_value)

@deprecate_kwarg(old_arg_name='encoding', new_arg_name=None)
def to_stata(self, fname, convert_dates=None, write_index=True,
Expand Down
5 changes: 5 additions & 0 deletions pandas/core/generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -1940,11 +1940,16 @@ def to_dense(self):
"""
Return dense representation of NDFrame (as opposed to sparse).

.. deprecated:: 0.25.0

Returns
-------
%(klass)s
Dense %(klass)s.
"""
warnings.warn("DataFrame/Series.to_dense is deprecated "
"and will be removed in a future version",
FutureWarning, stacklevel=2)
# compat
return self

Expand Down
6 changes: 3 additions & 3 deletions pandas/core/groupby/ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -630,9 +630,9 @@ def _aggregate_series_fast(self, obj, func):
group_index, _, ngroups = self.group_info

# avoids object / Series creation overhead
dummy = obj._get_values(slice(None, 0)).to_dense()
dummy = obj._get_values(slice(None, 0))
indexer = get_group_index_sorter(group_index, ngroups)
obj = obj._take(indexer).to_dense()
obj = obj._take(indexer)
group_index = algorithms.take_nd(
group_index, indexer, allow_fill=False)
grouper = reduction.SeriesGrouper(obj, func, group_index, ngroups,
Expand Down Expand Up @@ -879,7 +879,7 @@ def apply(self, f):
class SeriesSplitter(DataSplitter):

def _chop(self, sdata, slice_obj):
return sdata._get_values(slice_obj).to_dense()
return sdata._get_values(slice_obj)


class FrameSplitter(DataSplitter):
Expand Down
13 changes: 10 additions & 3 deletions pandas/core/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -1592,6 +1592,8 @@ def to_sparse(self, kind='block', fill_value=None):
"""
Convert Series to SparseSeries.

.. deprecated:: 0.25.0

Parameters
----------
kind : {'block', 'integer'}, default 'block'
Expand All @@ -1603,12 +1605,17 @@ def to_sparse(self, kind='block', fill_value=None):
SparseSeries
Sparse representation of the Series.
"""

warnings.warn("Series.to_sparse is deprecated and will be removed "
"in a future version", FutureWarning, stacklevel=2)
from pandas.core.sparse.series import SparseSeries

values = SparseArray(self, kind=kind, fill_value=fill_value)
return SparseSeries(
values, index=self.index, name=self.name
).__finalize__(self)
with warnings.catch_warnings():
warnings.filterwarnings("ignore", message="SparseSeries")
return SparseSeries(
values, index=self.index, name=self.name
).__finalize__(self)

def _set_name(self, name, inplace=False):
"""
Expand Down
15 changes: 15 additions & 0 deletions pandas/core/sparse/frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -282,6 +282,21 @@ def _unpickle_sparse_frame_compat(self, state):

@Appender(SparseFrameAccessor.to_dense.__doc__)
def to_dense(self):
"""
.. deprecated:: 0.25.0
Use Dataframe.sparse.to_dense() instead
"""

warning_message = """\
SparseDataFrame.to_dense is deprecated and will be removed in a future version

Use Dataframe.sparse.to_dense() instead

>>> df = pd.DataFrame({"A": pd.SparseArray([0, 1, 0])})
>>> df.sparse.to_dense()
"""
warnings.warn(warning_message, FutureWarning, stacklevel=2)

return SparseFrameAccessor(self).to_dense()

def _apply_columns(self, func):
Expand Down
6 changes: 6 additions & 0 deletions pandas/core/sparse/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -432,10 +432,16 @@ def to_dense(self):
"""
Convert SparseSeries to a Series.

.. deprecated:: 0.25.0

Returns
-------
s : Series
"""
warnings.warn("SparseSeries.to_dense is deprecated "
"and will be removed in a future version",
FutureWarning, stacklevel=2)

return Series(self.values.to_dense(), index=self.index,
name=self.name)

Expand Down
1 change: 1 addition & 0 deletions pandas/tests/arrays/sparse/test_arithmetics.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
class TestSparseArrayArithmetics:

_base = np.array
Expand Down
20 changes: 20 additions & 0 deletions pandas/tests/frame/test_deprecations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import numpy as np
import pytest

import pandas as pd
from pandas.util import testing as tm


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
def test_deprecated_to_sparse():
# GH 26557
# Deprecated 0.25.0

df = pd.DataFrame({"A": [1, np.nan, 3]})
sparse_df = pd.SparseDataFrame({"A": [1, np.nan, 3]})

# Deprecated 0.25.0
with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
result = df.to_sparse()
tm.assert_frame_equal(result, sparse_df)
14 changes: 14 additions & 0 deletions pandas/tests/generic/test_generic.py
Original file line number Diff line number Diff line change
Expand Up @@ -918,3 +918,17 @@ def test_axis_classmethods(self, box):
assert obj._get_axis_name(v) == box._get_axis_name(v)
assert obj._get_block_manager_axis(v) == \
box._get_block_manager_axis(v)

def test_deprecated_to_dense(self):
# GH 26557: DEPR
# Deprecated 0.25.0

df = pd.DataFrame({"A": [1, 2, 3]})
with tm.assert_produces_warning(FutureWarning):
result = df.to_dense()
tm.assert_frame_equal(result, df)

ser = pd.Series([1, 2, 3])
with tm.assert_produces_warning(FutureWarning):
result = ser.to_dense()
tm.assert_series_equal(result, ser)
2 changes: 2 additions & 0 deletions pandas/tests/io/json/test_pandas.py
Original file line number Diff line number Diff line change
Expand Up @@ -1013,6 +1013,8 @@ def test_datetime_tz(self):
assert stz.to_json() == s_naive.to_json()

@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:DataFrame.to_sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
def test_sparse(self):
# GH4377 df.to_json segfaults with non-ndarray blocks
df = pd.DataFrame(np.random.randn(10, 4))
Expand Down
2 changes: 2 additions & 0 deletions pandas/tests/io/test_packers.py
Original file line number Diff line number Diff line change
Expand Up @@ -551,6 +551,8 @@ def test_dataframe_duplicate_column_names(self):


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:DataFrame.to_sparse:FutureWarning")
class TestSparse(TestPackers):

def _check_roundtrip(self, obj, comparator, **kwargs):
Expand Down
10 changes: 10 additions & 0 deletions pandas/tests/io/test_pytables.py
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@
"ignore:object name:tables.exceptions.NaturalNameWarning"
)
ignore_sparse = pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
ignore_dataframe_tosparse = pytest.mark.filterwarnings(
"ignore:DataFrame.to_sparse:FutureWarning"
)
ignore_series_tosparse = pytest.mark.filterwarnings(
"ignore:Series.to_sparse:FutureWarning"
)

# contextmanager to ensure the file cleanup

Expand Down Expand Up @@ -2245,6 +2251,7 @@ def test_series(self):
check_index_type=False)

@ignore_sparse
@ignore_series_tosparse
def test_sparse_series(self):

s = tm.makeStringSeries()
Expand All @@ -2262,6 +2269,7 @@ def test_sparse_series(self):
check_series_type=True)

@ignore_sparse
@ignore_dataframe_tosparse
def test_sparse_frame(self):

s = tm.makeDataFrame()
Expand Down Expand Up @@ -2601,6 +2609,7 @@ def test_overwrite_node(self):
tm.assert_series_equal(store['a'], ts)

@ignore_sparse
@ignore_dataframe_tosparse
def test_sparse_with_compression(self):

# GH 2931
Expand Down Expand Up @@ -3746,6 +3755,7 @@ def test_start_stop_multiple(self):
tm.assert_frame_equal(result, expected)

@ignore_sparse
@ignore_dataframe_tosparse
def test_start_stop_fixed(self):

with ensure_clean_store(self.path) as store:
Expand Down
1 change: 1 addition & 0 deletions pandas/tests/series/test_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,7 @@ def test_sort_index_name(self):
assert result.name == self.ts.name

@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
def test_to_sparse_pass_name(self):
result = self.ts.to_sparse()
assert result.name == self.ts.name
Expand Down
13 changes: 7 additions & 6 deletions pandas/tests/series/test_combine_concat.py
Original file line number Diff line number Diff line change
Expand Up @@ -212,6 +212,7 @@ def test_combine_first_dt_tz_values(self, tz_naive_fixture):
assert_series_equal(exp, result)

@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
def test_concat_empty_series_dtypes(self):

# booleans
Expand Down Expand Up @@ -244,16 +245,16 @@ def test_concat_empty_series_dtypes(self):

# sparse
# TODO: move?
result = pd.concat([Series(dtype='float64').to_sparse(), Series(
dtype='float64').to_sparse()])
result = pd.concat([Series(dtype='float64').to_sparse(),
Series(dtype='float64').to_sparse()])
assert result.dtype == 'Sparse[float64]'

# GH 26705 - Assert .ftype is deprecated
with tm.assert_produces_warning(FutureWarning):
assert result.ftype == 'float64:sparse'

result = pd.concat([Series(dtype='float64').to_sparse(), Series(
dtype='float64')])
result = pd.concat([Series(dtype='float64').to_sparse(),
Series(dtype='float64')])
# TODO: release-note: concat sparse dtype
expected = pd.core.sparse.api.SparseDtype(np.float64)
assert result.dtype == expected
Expand All @@ -262,8 +263,8 @@ def test_concat_empty_series_dtypes(self):
with tm.assert_produces_warning(FutureWarning):
assert result.ftype == 'float64:sparse'

result = pd.concat([Series(dtype='float64').to_sparse(), Series(
dtype='object')])
result = pd.concat([Series(dtype='float64').to_sparse(),
Series(dtype='object')])
# TODO: release-note: concat sparse dtype
expected = pd.core.sparse.api.SparseDtype('object')
assert result.dtype == expected
Expand Down
21 changes: 21 additions & 0 deletions pandas/tests/series/test_deprecations.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import numpy as np
import pytest

import pandas as pd
from pandas import Series
from pandas.util import testing as tm


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
def test_deprecated_to_sparse():
# GH 26557
# Deprecated 0.25.0

ser = Series([1, np.nan, 3])
sparse_ser = pd.SparseSeries([1, np.nan, 3])

# Deprecated 0.25.0
with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
result = ser.to_sparse()
tm.assert_series_equal(result, sparse_ser)
2 changes: 2 additions & 0 deletions pandas/tests/series/test_missing.py
Original file line number Diff line number Diff line change
Expand Up @@ -781,6 +781,7 @@ def test_series_fillna_limit(self):
assert_series_equal(result, expected)

@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
def test_sparse_series_fillna_limit(self):
index = np.arange(10)
s = Series(np.random.randn(10), index=index)
Expand Down Expand Up @@ -809,6 +810,7 @@ def test_sparse_series_fillna_limit(self):
assert_series_equal(result, expected)

@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
def test_sparse_series_pad_backfill_limit(self):
index = np.arange(10)
s = Series(np.random.randn(10), index=index)
Expand Down
2 changes: 2 additions & 0 deletions pandas/tests/sparse/frame/test_apply.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ def fill_frame(frame):


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
def test_apply(frame):
applied = frame.apply(np.sqrt)
assert isinstance(applied, SparseDataFrame)
Expand Down Expand Up @@ -72,6 +73,7 @@ def test_apply_empty(empty):


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:DataFrame.to_sparse:FutureWarning")
def test_apply_nonuq():
orig = DataFrame([[1, 2, 3], [4, 5, 6], [7, 8, 9]],
index=['a', 'a', 'c'])
Expand Down
17 changes: 17 additions & 0 deletions pandas/tests/sparse/frame/test_frame.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@ def test_deprecated():


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:Series.to_sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:DataFrame.to_sparse:FutureWarning")
class TestSparseDataFrame(SharedWithSparse):
klass = SparseDataFrame

Expand Down Expand Up @@ -1294,6 +1296,7 @@ def test_default_fill_value_with_no_data(self):


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:DataFrame.to_sparse:FutureWarning")
class TestSparseDataFrameArithmetic:

def test_numeric_op_scalar(self):
Expand Down Expand Up @@ -1324,6 +1327,7 @@ def test_comparison_op_scalar(self):


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:DataFrame.to_sparse:FutureWarning")
class TestSparseDataFrameAnalytics:

def test_cumsum(self, float_frame):
Expand Down Expand Up @@ -1415,3 +1419,16 @@ def test_dropna(self, inplace, how):
if inplace:
result_df = input_df
tm.assert_sp_frame_equal(expected, result_df)


def test_deprecated_to_dense():
# GH 26557
# Deprecated 0.25.0

df = pd.DataFrame({"A": [1, np.nan, 3]})

with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
sparse_df = pd.SparseDataFrame({"A": [1, np.nan, 3]})
result = sparse_df.to_dense()
tm.assert_frame_equal(result, df)
1 change: 1 addition & 0 deletions pandas/tests/sparse/frame/test_to_csv.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@


@pytest.mark.filterwarnings("ignore:Sparse:FutureWarning")
@pytest.mark.filterwarnings("ignore:DataFrame.to_sparse:FutureWarning")
class TestSparseDataFrameToCsv:
fill_values = [np.nan, 0, None, 1]

Expand Down
Loading