diff --git a/doc/source/release.rst b/doc/source/release.rst index cac49a53e8fc5..f32ea44ed6242 100644 --- a/doc/source/release.rst +++ b/doc/source/release.rst @@ -368,6 +368,7 @@ Bug Fixes - Bug in concatenation with duplicate columns across dtypes not merging with axis=0 (:issue:`4771`) - Bug in ``iloc`` with a slice index failing (:issue:`4771`) - Incorrect error message with no colspecs or width in ``read_fwf``. (:issue:`4774`) + - Fix bugs in indexing in a Series with a duplicate index (:issue:`4548`, :issue:`4550`) pandas 0.12.0 ------------- diff --git a/pandas/core/generic.py b/pandas/core/generic.py index 58e1fbc4f177d..f4c5eb808689c 100644 --- a/pandas/core/generic.py +++ b/pandas/core/generic.py @@ -7,7 +7,7 @@ import pandas as pd from pandas.core.base import PandasObject -from pandas.core.index import Index, MultiIndex, _ensure_index +from pandas.core.index import Index, MultiIndex, _ensure_index, InvalidIndexError import pandas.core.indexing as indexing from pandas.core.indexing import _maybe_convert_indices from pandas.tseries.index import DatetimeIndex @@ -2308,6 +2308,10 @@ def where(self, cond, other=np.nan, inplace=False, try_cast=False, raise_on_erro _, other = self.align(other, join='left', fill_value=np.nan) + # if we are NOT aligned, raise as we cannot where index + if not all([ other._get_axis(i).equals(ax) for i, ax in enumerate(self.axes) ]): + raise InvalidIndexError + # slice me out of the other else: raise NotImplemented diff --git a/pandas/core/series.py b/pandas/core/series.py index 5579e60ceb90e..4f67fb1afdd5f 100644 --- a/pandas/core/series.py +++ b/pandas/core/series.py @@ -1037,9 +1037,13 @@ def __setitem__(self, key, value): if _is_bool_indexer(key): key = _check_bool_indexer(self.index, key) - self.where(~key, value, inplace=True) - else: - self._set_with(key, value) + try: + self.where(~key, value, inplace=True) + return + except (InvalidIndexError): + pass + + self._set_with(key, value) def _set_with_engine(self, key, value): values = self.values diff --git a/pandas/tests/test_series.py b/pandas/tests/test_series.py index b0911ed10be20..7f8fa1019261f 100644 --- a/pandas/tests/test_series.py +++ b/pandas/tests/test_series.py @@ -1373,6 +1373,26 @@ def test_where_inplace(self): rs.where(cond, -s, inplace=True) assert_series_equal(rs, s.where(cond, -s)) + def test_where_dups(self): + # GH 4550 + # where crashes with dups in index + s1 = Series(list(range(3))) + s2 = Series(list(range(3))) + comb = pd.concat([s1,s2]) + result = comb.where(comb < 2) + expected = Series([0,1,np.nan,0,1,np.nan],index=[0,1,2,0,1,2]) + assert_series_equal(result, expected) + + # GH 4548 + # inplace updating not working with dups + comb[comb<1] = 5 + expected = Series([5,1,2,5,1,2],index=[0,1,2,0,1,2]) + assert_series_equal(comb, expected) + + comb[comb<2] += 10 + expected = Series([5,11,2,5,11,2],index=[0,1,2,0,1,2]) + assert_series_equal(comb, expected) + def test_mask(self): s = Series(np.random.randn(5)) cond = s > 0