Skip to content

Commit 3653994

Browse files
committed
Merge pull request #4833 from jreback/series_loc
BUG: Fixed an issue with a duplicate index and duplicate selector with loc (GH4825)
2 parents 8a06d22 + a0abef8 commit 3653994

File tree

3 files changed

+57
-5
lines changed

3 files changed

+57
-5
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -411,6 +411,7 @@ Bug Fixes
411411
- Fixed an issue related to ticklocs/ticklabels with log scale bar plots
412412
across different versions of matplotlib (:issue:`4789`)
413413
- Suppressed DeprecationWarning associated with internal calls issued by repr() (:issue:`4391`)
414+
- Fixed an issue with a duplicate index and duplicate selector with ``.loc`` (:issue:`4825`)
414415

415416
pandas 0.12.0
416417
-------------

pandas/core/indexing.py

+13-5
Original file line numberDiff line numberDiff line change
@@ -701,19 +701,27 @@ def _reindex(keys, level=None):
701701
new_labels[cur_indexer] = cur_labels
702702
new_labels[missing_indexer] = missing_labels
703703

704+
# reindex with the specified axis
705+
ndim = self.obj.ndim
706+
if axis+1 > ndim:
707+
raise AssertionError("invalid indexing error with non-unique index")
708+
704709
# a unique indexer
705710
if keyarr_is_unique:
706711
new_indexer = (Index(cur_indexer) + Index(missing_indexer)).values
707712
new_indexer[missing_indexer] = -1
708713

709714
# we have a non_unique selector, need to use the original indexer here
710715
else:
711-
new_indexer = indexer
712716

713-
# reindex with the specified axis
714-
ndim = self.obj.ndim
715-
if axis+1 > ndim:
716-
raise AssertionError("invalid indexing error with non-unique index")
717+
# need to retake to have the same size as the indexer
718+
rindexer = indexer.values
719+
rindexer[~check] = 0
720+
result = self.obj.take(rindexer, axis=axis, convert=False)
721+
722+
# reset the new indexer to account for the new size
723+
new_indexer = np.arange(len(result))
724+
new_indexer[~check] = -1
717725

718726
result = result._reindex_with_indexers({ axis : [ new_labels, new_indexer ] }, copy=True, allow_dups=True)
719727

pandas/tests/test_indexing.py

+43
Original file line numberDiff line numberDiff line change
@@ -1436,6 +1436,49 @@ def f():
14361436
p.loc[:,:,'C'] = Series([30,32],index=p_orig.items)
14371437
assert_panel_equal(p,expected)
14381438

1439+
def test_series_partial_set(self):
1440+
# partial set with new index
1441+
# Regression from GH4825
1442+
ser = Series([0.1, 0.2], index=[1, 2])
1443+
1444+
# loc
1445+
expected = Series([np.nan, 0.2, np.nan], index=[3, 2, 3])
1446+
result = ser.loc[[3, 2, 3]]
1447+
assert_series_equal(result, expected)
1448+
1449+
expected = Series([np.nan, np.nan, np.nan], index=[3, 3, 3])
1450+
result = ser.loc[[3, 3, 3]]
1451+
assert_series_equal(result, expected)
1452+
1453+
expected = Series([0.2, 0.2, np.nan], index=[2, 2, 3])
1454+
result = ser.loc[[2, 2, 3]]
1455+
assert_series_equal(result, expected)
1456+
1457+
expected = Series([0.3, np.nan, np.nan], index=[3, 4, 4])
1458+
result = Series([0.1, 0.2, 0.3], index=[1,2,3]).loc[[3,4,4]]
1459+
assert_series_equal(result, expected)
1460+
1461+
expected = Series([np.nan, 0.3, 0.3], index=[5, 3, 3])
1462+
result = Series([0.1, 0.2, 0.3, 0.4], index=[1,2,3,4]).loc[[5,3,3]]
1463+
assert_series_equal(result, expected)
1464+
1465+
expected = Series([np.nan, 0.4, 0.4], index=[5, 4, 4])
1466+
result = Series([0.1, 0.2, 0.3, 0.4], index=[1,2,3,4]).loc[[5,4,4]]
1467+
assert_series_equal(result, expected)
1468+
1469+
expected = Series([0.4, np.nan, np.nan], index=[7, 2, 2])
1470+
result = Series([0.1, 0.2, 0.3, 0.4], index=[4,5,6,7]).loc[[7,2,2]]
1471+
assert_series_equal(result, expected)
1472+
1473+
expected = Series([0.4, np.nan, np.nan], index=[4, 5, 5])
1474+
result = Series([0.1, 0.2, 0.3, 0.4], index=[1,2,3,4]).loc[[4,5,5]]
1475+
assert_series_equal(result, expected)
1476+
1477+
# iloc
1478+
expected = Series([0.2,0.2,0.1,0.1], index=[2,2,1,1])
1479+
result = ser.iloc[[1,1,0,0]]
1480+
assert_series_equal(result, expected)
1481+
14391482
if __name__ == '__main__':
14401483
import nose
14411484
nose.runmodule(argv=[__file__, '-vvs', '-x', '--pdb', '--pdb-failure'],

0 commit comments

Comments
 (0)