Skip to content

Commit 874714d

Browse files
committed
Merge pull request #4522 from jreback/mi_dups
BUG: GH4516 Fixed issue with sorting a duplicate multi-index that has multiple dtypes
2 parents 7261d43 + a12da2c commit 874714d

File tree

4 files changed

+30
-5
lines changed

4 files changed

+30
-5
lines changed

doc/source/release.rst

+1
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,7 @@ pandas 0.13
135135
- Raise on set indexing with a Panel and a Panel as a value which needs alignment (:issue:`3777`)
136136
- frozenset objects now raise in the ``Series`` constructor (:issue:`4482`,
137137
:issue:`4480`)
138+
- Fixed issue with sorting a duplicate multi-index that has multiple dtypes (:issue:`4516`)
138139

139140
pandas 0.12
140141
===========

pandas/core/frame.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -3304,10 +3304,13 @@ def sortlevel(self, level=0, axis=0, ascending=True, inplace=False):
33043304
new_axis, indexer = the_axis.sortlevel(level, ascending=ascending)
33053305

33063306
if self._is_mixed_type and not inplace:
3307-
if axis == 0:
3308-
return self.reindex(index=new_axis)
3307+
ax = 'index' if axis == 0 else 'columns'
3308+
3309+
if new_axis.is_unique:
3310+
d = { ax : new_axis }
33093311
else:
3310-
return self.reindex(columns=new_axis)
3312+
d = { ax : indexer, 'takeable' : True }
3313+
return self.reindex(**d)
33113314

33123315
if inplace:
33133316
if axis == 1:

pandas/core/index.py

+11-2
Original file line numberDiff line numberDiff line change
@@ -2165,8 +2165,17 @@ def reindex(self, target, method=None, level=None, limit=None,
21652165
if self.equals(target):
21662166
indexer = None
21672167
else:
2168-
indexer = self.get_indexer(target, method=method,
2169-
limit=limit)
2168+
if self.is_unique:
2169+
indexer = self.get_indexer(target, method=method,
2170+
limit=limit)
2171+
else:
2172+
if takeable:
2173+
if method is not None or limit is not None:
2174+
raise ValueError("cannot do a takeable reindex with "
2175+
"with a method or limit")
2176+
return self[target], target
2177+
2178+
raise Exception("cannot handle a non-takeable non-unique multi-index!")
21702179

21712180
if not isinstance(target, MultiIndex):
21722181
if indexer is None:

pandas/tests/test_multilevel.py

+12
Original file line numberDiff line numberDiff line change
@@ -1828,6 +1828,18 @@ def test_duplicate_groupby_issues(self):
18281828
result = s.groupby(s.index).first()
18291829
self.assertEquals(len(result), 3)
18301830

1831+
def test_duplicate_mi(self):
1832+
# GH 4516
1833+
df = DataFrame([['foo','bar',1.0,1],['foo','bar',2.0,2],['bah','bam',3.0,3],
1834+
['bah','bam',4.0,4],['foo','bar',5.0,5],['bah','bam',6.0,6]],
1835+
columns=list('ABCD'))
1836+
df = df.set_index(['A','B'])
1837+
df = df.sortlevel(0)
1838+
result = df.loc[('foo','bar')]
1839+
expected = DataFrame([['foo','bar',1.0,1],['foo','bar',2.0,2],['foo','bar',5.0,5]],
1840+
columns=list('ABCD')).set_index(['A','B'])
1841+
assert_frame_equal(result,expected)
1842+
18311843
def test_multiindex_set_index(self):
18321844
# segfault in #3308
18331845
d = {'t1': [2, 2.5, 3], 't2': [4, 5, 6]}

0 commit comments

Comments
 (0)