Skip to content

Commit b8b4a69

Browse files
committed
BUG: Bug in Index construction with a mixed list of tuples #10697)
1 parent 92da9ed commit b8b4a69

File tree

4 files changed

+31
-10
lines changed

4 files changed

+31
-10
lines changed

doc/source/whatsnew/v0.17.0.txt

+1-1
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ Bug Fixes
367367
- Bug in ``Index.drop_duplicates`` dropping name(s) (:issue:`10115`)
368368
- Bug in ``pd.Series`` when setting a value on an empty ``Series`` whose index has a frequency. (:issue:`10193`)
369369
- Bug in ``DataFrame.plot`` raises ``ValueError`` when color name is specified by multiple characters (:issue:`10387`)
370-
370+
- Bug in ``Index`` construction with a mixed list of tuples (:issue:`10697`)
371371
- Bug in ``DataFrame.reset_index`` when index contains `NaT`. (:issue:`10388`)
372372
- Bug in ``ExcelReader`` when worksheet is empty (:issue:`6403`)
373373
- Bug in ``Table.select_column`` where name is not preserved (:issue:`10392`)

pandas/core/index.py

+14-9
Original file line numberDiff line numberDiff line change
@@ -164,16 +164,21 @@ def __new__(cls, data=None, dtype=None, copy=False, name=None, fastpath=False,
164164
cls._scalar_data_error(data)
165165
else:
166166
if tupleize_cols and isinstance(data, list) and data and isinstance(data[0], tuple):
167-
try:
168167

169-
# must be orderable in py3
170-
if compat.PY3:
171-
sorted(data)
172-
return MultiIndex.from_tuples(
173-
data, names=name or kwargs.get('names'))
174-
except (TypeError, KeyError):
175-
# python2 - MultiIndex fails on mixed types
176-
pass
168+
# we must be all tuples, otherwise don't construct
169+
# 10697
170+
if all( isinstance(e, tuple) for e in data ):
171+
172+
try:
173+
174+
# must be orderable in py3
175+
if compat.PY3:
176+
sorted(data)
177+
return MultiIndex.from_tuples(
178+
data, names=name or kwargs.get('names'))
179+
except (TypeError, KeyError):
180+
# python2 - MultiIndex fails on mixed types
181+
pass
177182

178183
# other iterable of some kind
179184
subarr = com._asarray_tuplesafe(data, dtype=object)

pandas/tests/test_index.py

+9
Original file line numberDiff line numberDiff line change
@@ -553,6 +553,15 @@ def test_constructor_corner(self):
553553
# corner case
554554
self.assertRaises(TypeError, Index, 0)
555555

556+
def test_consruction_list_mixed_tuples(self):
557+
# 10697
558+
# if we are constructing from a mixed list of tuples, make sure that we
559+
# are independent of the sorting order
560+
idx1 = Index([('A',1),'B'])
561+
self.assertIsInstance(idx1, Index) and self.assertNotInstance(idx1, MultiIndex)
562+
idx2 = Index(['B',('A',1)])
563+
self.assertIsInstance(idx2, Index) and self.assertNotInstance(idx2, MultiIndex)
564+
556565
def test_constructor_from_series(self):
557566

558567
expected = DatetimeIndex([Timestamp('20110101'),Timestamp('20120101'),Timestamp('20130101')])

pandas/tools/tests/test_merge.py

+7
Original file line numberDiff line numberDiff line change
@@ -2002,6 +2002,13 @@ def test_dups_index(self):
20022002
result = df.append(df)
20032003
assert_frame_equal(result, expected)
20042004

2005+
def test_with_mixed_tuples(self):
2006+
# 10697
2007+
# columns have mixed tuples, so handle properly
2008+
df1 = DataFrame({ u'A' : 'foo', (u'B',1) : 'bar' },index=range(2))
2009+
df2 = DataFrame({ u'B' : 'foo', (u'B',1) : 'bar' },index=range(2))
2010+
result = concat([df1,df2])
2011+
20052012
def test_join_dups(self):
20062013

20072014
# joining dups

0 commit comments

Comments
 (0)