diff --git a/pandas/core/sorting.py b/pandas/core/sorting.py index 27252b9616a44..a0cc196728e4b 100644 --- a/pandas/core/sorting.py +++ b/pandas/core/sorting.py @@ -431,11 +431,14 @@ def safe_sort(values, labels=None, na_sentinel=-1, assume_unique=False): def sort_mixed(values): # order ints before strings, safe in py3 + num_pos = np.array([isinstance(x, (float, int, long)) for x in values], + dtype=bool) str_pos = np.array([isinstance(x, string_types) for x in values], dtype=bool) - nums = np.sort(values[~str_pos]) + nums = np.sort(values[num_pos]) strs = np.sort(values[str_pos]) - return np.concatenate([nums, np.asarray(strs, dtype=object)]) + others = values[~(str_pos | num_pos)] # We don't bother sorting these + return np.concatenate([nums, np.asarray(strs, dtype=object), others]) sorter = None if PY3 and lib.infer_dtype(values) == 'mixed-integer': @@ -445,7 +448,9 @@ def sort_mixed(values): try: sorter = values.argsort() ordered = values.take(sorter) - except TypeError: + except (ValueError, TypeError): + # Period comparison may raise IncompatibleFrequency, which + # subclasses ValueError instead of TypeError # try this anyway ordered = sort_mixed(values) diff --git a/pandas/tests/indexes/period/test_period.py b/pandas/tests/indexes/period/test_period.py index e5ee078d3558d..eb7f47736c96f 100644 --- a/pandas/tests/indexes/period/test_period.py +++ b/pandas/tests/indexes/period/test_period.py @@ -11,6 +11,36 @@ from ..datetimelike import DatetimeLike +class TestPeriodLevelMultiIndex(object): + # TODO: Is there a more appropriate place for these? + def test_set_index(self): + # GH#17112 + index = Index(['PCE'] * 4, name='Variable') + data = [Period('2018Q2'), + Period('2021', freq='5A-Dec'), + Period('2026', freq='10A-Dec'), + Period('2017Q2')] + ser = Series(data, index=index, name='Period') + df = ser.to_frame() + + res = df.set_index('Period', append=True) + # If the doesn't raise then that's a good start + assert res.index.names == ['Variable', 'Period'] + + def test_from_arrays_period_level(self): + # GH#17112 + index = Index(['PCE'] * 4, name='Variable') + data = [Period('2018Q2'), + Period('2021', freq='5A-Dec'), + Period('2026', freq='10A-Dec'), + Period('2017Q2')] + ser = Series(data, index=index, name='Period') + + mi = pd.MultiIndex.from_arrays([ser.index, ser]) + assert mi.names == ['Variable', 'Period'] + assert mi.get_level_values('Variable').equals(index) + + class TestPeriodIndex(DatetimeLike): _holder = PeriodIndex _multiprocess_can_split_ = True