Skip to content

Commit

Permalink
CLN: Removed levels attribute from Categorical
Browse files Browse the repository at this point in the history
Deprecated back in `0.15.0` and therefore long overdue.  Closes #8376.

Author: gfyoung <gfyoung17@gmail.com>

Closes #13612 from gfyoung/categorical-levels-remove and squashes the following commits:

f1254df [gfyoung] MAINT: Relocated backwards compat categorical pickle tests
f3321cb [gfyoung] CLN: Removed levels attribute from Categorical
  • Loading branch information
gfyoung authored and jreback committed Jul 15, 2016
1 parent 1bee56e commit d7c028d
Show file tree
Hide file tree
Showing 7 changed files with 43 additions and 80 deletions.
1 change: 1 addition & 0 deletions doc/source/whatsnew/v0.19.0.txt
Original file line number Diff line number Diff line change
Expand Up @@ -506,6 +506,7 @@ Removal of prior version deprecations/changes

- ``DataFrame.to_csv()`` has dropped the ``engine`` parameter, as was deprecated in 0.17.1 (:issue:`11274`, :issue:`13419`)
- ``DataFrame.to_dict()`` has dropped the ``outtype`` parameter in favor of ``orient`` (:issue:`13627`, :issue:`8486`)
- ``pd.Categorical`` has dropped the ``levels`` attribute in favour of ``categories`` (:issue:`8376`)


.. _whatsnew_0190.performance:
Expand Down
30 changes: 2 additions & 28 deletions pandas/core/categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,8 @@ class Categorical(PandasObject):
__array_priority__ = 1000
_typ = 'categorical'

def __init__(self, values, categories=None, ordered=False, name=None,
fastpath=False, levels=None):
def __init__(self, values, categories=None, ordered=False,
name=None, fastpath=False):

if fastpath:
# fast path
Expand All @@ -245,17 +245,6 @@ def __init__(self, values, categories=None, ordered=False, name=None,
"name=\"something\")'")
warn(msg, UserWarning, stacklevel=2)

# TODO: Remove after deprecation period in 2017/ after 0.18
if levels is not None:
warn("Creating a 'Categorical' with 'levels' is deprecated, use "
"'categories' instead", FutureWarning, stacklevel=2)
if categories is None:
categories = levels
else:
raise ValueError("Cannot pass in both 'categories' and "
"(deprecated) 'levels', use only "
"'categories'", stacklevel=2)

# sanitize input
if is_categorical_dtype(values):

Expand Down Expand Up @@ -580,21 +569,6 @@ def _get_categories(self):
categories = property(fget=_get_categories, fset=_set_categories,
doc=_categories_doc)

def _set_levels(self, levels):
""" set new levels (deprecated, use "categories") """
warn("Assigning to 'levels' is deprecated, use 'categories'",
FutureWarning, stacklevel=2)
self.categories = levels

def _get_levels(self):
""" Gets the levels (deprecated, use "categories") """
warn("Accessing 'levels' is deprecated, use 'categories'",
FutureWarning, stacklevel=2)
return self.categories

# TODO: Remove after deprecation period in 2017/ after 0.18
levels = property(fget=_get_levels, fset=_set_levels)

_ordered = None

def _set_ordered(self, value):
Expand Down
File renamed without changes.
File renamed without changes.
38 changes: 38 additions & 0 deletions pandas/io/tests/test_pickle.py
Original file line number Diff line number Diff line change
Expand Up @@ -231,6 +231,44 @@ def python_unpickler(path):
result = python_unpickler(path)
self.compare_element(result, expected, typ)

def test_pickle_v0_14_1(self):

# we have the name warning
# 10482
with tm.assert_produces_warning(UserWarning):
cat = pd.Categorical(values=['a', 'b', 'c'],
categories=['a', 'b', 'c', 'd'],
name='foobar', ordered=False)
pickle_path = os.path.join(tm.get_data_path(),
'categorical_0_14_1.pickle')
# This code was executed once on v0.14.1 to generate the pickle:
#
# cat = Categorical(labels=np.arange(3), levels=['a', 'b', 'c', 'd'],
# name='foobar')
# with open(pickle_path, 'wb') as f: pickle.dump(cat, f)
#
tm.assert_categorical_equal(cat, pd.read_pickle(pickle_path))

def test_pickle_v0_15_2(self):
# ordered -> _ordered
# GH 9347

# we have the name warning
# 10482
with tm.assert_produces_warning(UserWarning):
cat = pd.Categorical(values=['a', 'b', 'c'],
categories=['a', 'b', 'c', 'd'],
name='foobar', ordered=False)
pickle_path = os.path.join(tm.get_data_path(),
'categorical_0_15_2.pickle')
# This code was executed once on v0.15.2 to generate the pickle:
#
# cat = Categorical(labels=np.arange(3), levels=['a', 'b', 'c', 'd'],
# name='foobar')
# with open(pickle_path, 'wb') as f: pickle.dump(cat, f)
#
tm.assert_categorical_equal(cat, pd.read_pickle(pickle_path))


if __name__ == '__main__':
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],
Expand Down
50 changes: 0 additions & 50 deletions pandas/tests/test_categorical.py
Original file line number Diff line number Diff line change
Expand Up @@ -1559,18 +1559,6 @@ def test_deprecated_labels(self):
res = cat.labels
self.assert_numpy_array_equal(res, exp)

def test_deprecated_levels(self):
# TODO: levels is deprecated and should be removed in 0.18 or 2017,
# whatever is earlier
cat = pd.Categorical([1, 2, 3, np.nan], categories=[1, 2, 3])
exp = cat.categories
with tm.assert_produces_warning(FutureWarning):
res = cat.levels
self.assert_index_equal(res, exp)
with tm.assert_produces_warning(FutureWarning):
res = pd.Categorical([1, 2, 3, np.nan], levels=[1, 2, 3])
self.assert_index_equal(res.categories, exp)

def test_removed_names_produces_warning(self):

# 10482
Expand Down Expand Up @@ -4431,44 +4419,6 @@ def test_dt_accessor_api_for_categorical(self):
invalid.dt
self.assertFalse(hasattr(invalid, 'str'))

def test_pickle_v0_14_1(self):

# we have the name warning
# 10482
with tm.assert_produces_warning(UserWarning):
cat = pd.Categorical(values=['a', 'b', 'c'],
categories=['a', 'b', 'c', 'd'],
name='foobar', ordered=False)
pickle_path = os.path.join(tm.get_data_path(),
'categorical_0_14_1.pickle')
# This code was executed once on v0.14.1 to generate the pickle:
#
# cat = Categorical(labels=np.arange(3), levels=['a', 'b', 'c', 'd'],
# name='foobar')
# with open(pickle_path, 'wb') as f: pickle.dump(cat, f)
#
self.assert_categorical_equal(cat, pd.read_pickle(pickle_path))

def test_pickle_v0_15_2(self):
# ordered -> _ordered
# GH 9347

# we have the name warning
# 10482
with tm.assert_produces_warning(UserWarning):
cat = pd.Categorical(values=['a', 'b', 'c'],
categories=['a', 'b', 'c', 'd'],
name='foobar', ordered=False)
pickle_path = os.path.join(tm.get_data_path(),
'categorical_0_15_2.pickle')
# This code was executed once on v0.15.2 to generate the pickle:
#
# cat = Categorical(labels=np.arange(3), levels=['a', 'b', 'c', 'd'],
# name='foobar')
# with open(pickle_path, 'wb') as f: pickle.dump(cat, f)
#
self.assert_categorical_equal(cat, pd.read_pickle(pickle_path))

def test_concat_categorical(self):
# See GH 10177
df1 = pd.DataFrame(
Expand Down
4 changes: 2 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,7 @@ def pxd(name):
'tests/data/legacy_msgpack/*/*.msgpack',
'tests/data/*.csv*',
'tests/data/*.dta',
'tests/data/*.pickle',
'tests/data/*.txt',
'tests/data/*.xls',
'tests/data/*.xlsx',
Expand All @@ -605,8 +606,7 @@ def pxd(name):
'tests/data/html_encoding/*.html',
'tests/json/data/*.json'],
'pandas.tools': ['tests/data/*.csv'],
'pandas.tests': ['data/*.pickle',
'data/*.csv'],
'pandas.tests': ['data/*.csv'],
'pandas.tests.formats': ['data/*.csv'],
'pandas.tests.indexes': ['data/*.pickle'],
'pandas.tseries.tests': ['data/*.pickle',
Expand Down

0 comments on commit d7c028d

Please sign in to comment.