Skip to content

Commit fff7b89

Browse files
Chang Shewesm
Chang She
authored andcommitted
BUG: unordered dup index does not yield scalar value #1586
1 parent 58b5afa commit fff7b89

File tree

3 files changed

+21
-4
lines changed

3 files changed

+21
-4
lines changed

pandas/src/engines.pyx

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,6 @@ cdef class IndexEngine:
137137

138138
if self.is_monotonic:
139139
values = self._get_index_values()
140-
141140
left = values.searchsorted(val, side='left')
142141
right = values.searchsorted(val, side='right')
143142

@@ -149,14 +148,15 @@ cdef class IndexEngine:
149148
else:
150149
return slice(left, right)
151150
else:
152-
return self._get_bool_indexer(val)
151+
return self._maybe_get_bool_indexer(val)
153152

154-
cdef _get_bool_indexer(self, object val):
153+
cdef _maybe_get_bool_indexer(self, object val):
155154
cdef:
156155
ndarray[uint8_t] indexer
157156
ndarray[object] values
158157
int count = 0
159158
Py_ssize_t i, n
159+
int last_true
160160

161161
values = self._get_index_values()
162162
n = len(values)
@@ -168,11 +168,14 @@ cdef class IndexEngine:
168168
if values[i] == val:
169169
count += 1
170170
indexer[i] = 1
171+
last_true = i
171172
else:
172173
indexer[i] = 0
173174

174175
if count == 0:
175176
raise KeyError(val)
177+
if count == 1:
178+
return last_true
176179

177180
return result
178181

@@ -275,13 +278,14 @@ cdef class Int64Engine(IndexEngine):
275278
return _algos.backfill_int64(self._get_index_values(), other,
276279
limit=limit)
277280

278-
cdef _get_bool_indexer(self, object val):
281+
cdef _maybe_get_bool_indexer(self, object val):
279282
cdef:
280283
ndarray[uint8_t, cast=True] indexer
281284
ndarray[int64_t] values
282285
int count = 0
283286
Py_ssize_t i, n
284287
int64_t ival
288+
int last_true
285289

286290
if not util.is_integer_object(val):
287291
raise KeyError(val)
@@ -298,11 +302,14 @@ cdef class Int64Engine(IndexEngine):
298302
if values[i] == val:
299303
count += 1
300304
indexer[i] = 1
305+
last_true = i
301306
else:
302307
indexer[i] = 0
303308

304309
if count == 0:
305310
raise KeyError(val)
311+
if count == 1:
312+
return last_true
306313

307314
return result
308315

pandas/tests/test_index.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,11 @@ def test_get_loc_duplicates(self):
999999
assert(result == expected)
10001000
# self.assertRaises(Exception, index.get_loc, 2)
10011001

1002+
index = Index(['c', 'a', 'a', 'b', 'b'])
1003+
rs = index.get_loc('c')
1004+
xp = 0
1005+
assert(rs == xp)
1006+
10021007
def test_get_loc_level(self):
10031008
index = MultiIndex(levels=[Index(range(4)),
10041009
Index(range(4)),

pandas/tests/test_series.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -599,6 +599,11 @@ def test_getitem_ambiguous_keyerror(self):
599599
self.assertRaises(KeyError, s.__getitem__, 1)
600600
self.assertRaises(KeyError, s.ix.__getitem__, 1)
601601

602+
def test_getitem_unordered_dup(self):
603+
obj = Series(range(5), index=['c', 'a', 'a', 'b', 'b'])
604+
self.assert_(np.isscalar(obj['c']))
605+
self.assert_(obj['c'] == 0)
606+
602607
def test_setitem_ambiguous_keyerror(self):
603608
s = Series(range(10), index=range(0, 20, 2))
604609
self.assertRaises(KeyError, s.__setitem__, 1, 5)

0 commit comments

Comments
 (0)