Skip to content

Commit

Permalink
ENH: Added FrozenList difference setop
Browse files Browse the repository at this point in the history
closes #15475

Author: Ben Thayer <benthayer2365@gmail.com>
Author: bthayer2365 <bthayer2365@users.noreply.github.com>

Closes #15506 from bthayer2365/frozen-index and squashes the following commits:

428a1b3 [Ben Thayer] Added __iadd__ test, fixed whatsnew
84ba405 [Ben Thayer] Merge branch 'master' of github.com:pandas-dev/pandas into frozen-index
8dbde1e [Ben Thayer] Rebased to upstream/master
6f6c140 [Ben Thayer] Added docstrings, depricated __iadd__, changed __add__ to use self.union()
66b3b91 [Ben Thayer] Fixed issue number
3d6cee5 [Ben Thayer] Depricated __add__ in favor of union
ccd75c7 [Ben Thayer] Changed __sub__ to difference
cd7de26 [Ben Thayer] Added versionadded tag in docs and renamed test_inplace to test_inplace_add for consistency
0ea8d21 [Ben Thayer] Added __isub__ and groupby example to docs
79dd958 [Ben Thayer] Updated whatsnew to reflect changes
0fc7e19 [Ben Thayer] Removed whitespace
73564ab [Ben Thayer] Added FrozenList subtraction
fee7a7d [bthayer2365] Merge branch 'master' into frozen-index
6a2b48d [Ben Thayer] Added docstrings, depricated __iadd__, changed __add__ to use self.union()
2ab85cb [Ben Thayer] Fixed issue number
cb95089 [Ben Thayer] Depricated __add__ in favor of union
2e43849 [Ben Thayer] Changed __sub__ to difference
fdcfbbb [Ben Thayer] Added versionadded tag in docs and renamed test_inplace to test_inplace_add for consistency
2fad2f7 [Ben Thayer] Added __isub__ and groupby example to docs
cd73faa [Ben Thayer] Updated whatsnew to reflect changes
f6381a8 [Ben Thayer] Removed whitespace
ada7cda [Ben Thayer] Added FrozenList subtraction
  • Loading branch information
benthayer authored and jreback committed Mar 2, 2017
1 parent d92a759 commit 37fe2c4
Show file tree
Hide file tree
Showing 4 changed files with 57 additions and 12 deletions.
10 changes: 10 additions & 0 deletions doc/source/groupby.rst
Expand Up @@ -126,6 +126,16 @@ We could naturally group by either the ``A`` or ``B`` columns or both:
grouped = df.groupby('A')
grouped = df.groupby(['A', 'B'])
.. versionadded:: 0.20

If we also have a MultiIndex on columns ``A`` and ``B``, we can group by all
but the specified columns.

.. ipython:: python
df2 = df.set_index(['A', 'B'])
grouped = df2.groupby(level=df2.index.names.difference(['B'])
These will split the DataFrame on its index (rows). We could also split by the
columns:
Expand Down
2 changes: 2 additions & 0 deletions doc/source/whatsnew/v0.20.0.txt
Expand Up @@ -28,6 +28,7 @@ New features

- Integration with the ``feather-format``, including a new top-level ``pd.read_feather()`` and ``DataFrame.to_feather()`` method, see :ref:`here <io.feather>`.
- ``.str.replace`` now accepts a callable, as replacement, which is passed to ``re.sub`` (:issue:`15055`)
- ``FrozenList`` has gained the ``.difference()`` setop method (:issue:`15475`)



Expand Down Expand Up @@ -534,6 +535,7 @@ Deprecations
- ``Series.sortlevel`` and ``DataFrame.sortlevel`` have been deprecated in favor of ``Series.sort_index`` and ``DataFrame.sort_index`` (:issue:`15099`)
- importing ``concat`` from ``pandas.tools.merge`` has been deprecated in favor of imports from the ``pandas`` namespace. This should only affect explict imports (:issue:`15358`)
- ``Series/DataFrame/Panel.consolidate()`` been deprecated as a public method. (:issue:`15483`)
- ``FrozenList`` addition (new object and inplace) have been deprecated in favor of the ``.union()`` method. (:issue: `15475`)

.. _whatsnew_0200.prior_deprecations:

Expand Down
24 changes: 21 additions & 3 deletions pandas/indexes/frozen.py
Expand Up @@ -13,6 +13,8 @@
from pandas.types.cast import _coerce_indexer_dtype
from pandas.formats.printing import pprint_thing

import warnings


class FrozenList(PandasObject, list):

Expand All @@ -25,11 +27,14 @@ class FrozenList(PandasObject, list):
# typechecks

def __add__(self, other):
warnings.warn("__add__ is deprecated, use union(...)", FutureWarning)
return self.union(other)

def __iadd__(self, other):
warnings.warn("__iadd__ is deprecated, use union(...)", FutureWarning)
if isinstance(other, tuple):
other = list(other)
return self.__class__(super(FrozenList, self).__add__(other))

__iadd__ = __add__
return super(FrozenList, self).__iadd__(other)

# Python 2 compat
def __getslice__(self, i, j):
Expand Down Expand Up @@ -80,6 +85,19 @@ def __repr__(self):
__setitem__ = __setslice__ = __delitem__ = __delslice__ = _disabled
pop = append = extend = remove = sort = insert = _disabled

def union(self, other):
"""Returns a FrozenList with other concatenated to the end of self"""
if isinstance(other, tuple):
other = list(other)
return self.__class__(super(FrozenList, self).__add__(other))

def difference(self, other):
"""Returns a FrozenList with the same elements as self, but with elements
that are also in other removed."""
other = set(other)
temp = [x for x in self if x not in other]
return self.__class__(temp)


class FrozenNDArray(PandasObject, np.ndarray):

Expand Down
33 changes: 24 additions & 9 deletions pandas/tests/indexes/test_frozen.py
Expand Up @@ -15,20 +15,35 @@ def setUp(self):
self.klass = FrozenList

def test_add(self):
result = self.container + (1, 2, 3)
q = FrozenList([1])
with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
q = q + [2, 3]
expected = FrozenList([1, 2, 3])
self.check_result(q, expected)

def test_iadd(self):
q = FrozenList([1])
with tm.assert_produces_warning(FutureWarning,
check_stacklevel=False):
q += [2, 3]
expected = FrozenList([1, 2, 3])
self.check_result(q, expected)

def test_union(self):
result = self.container.union((1, 2, 3))
expected = FrozenList(self.lst + [1, 2, 3])
self.check_result(result, expected)

result = (1, 2, 3) + self.container
expected = FrozenList([1, 2, 3] + self.lst)
def test_difference(self):
result = self.container.difference([2])
expected = FrozenList([1, 3, 4, 5])
self.check_result(result, expected)

def test_inplace(self):
q = r = self.container
q += [5]
self.check_result(q, self.lst + [5])
# other shouldn't be mutated
self.check_result(r, self.lst)
def test_difference_dupe(self):
result = FrozenList([1, 2, 3, 2]).difference([2])
expected = FrozenList([1, 3])
self.check_result(result, expected)


class TestFrozenNDArray(CheckImmutable, CheckStringMixin, tm.TestCase):
Expand Down

0 comments on commit 37fe2c4

Please sign in to comment.