diff --git a/RELEASE.rst b/RELEASE.rst index aac34c6cf8a5e..a3becfa2de3c7 100644 --- a/RELEASE.rst +++ b/RELEASE.rst @@ -54,6 +54,7 @@ pandas 0.12.0 - ``.loc`` was not raising when passed an integer list (GH3449_) - Unordered time series selection was misbehaving when using label slicing (GH3448_) - Duplicate indexes with getitem will return items in the correct order (GH3455_, GH3457_) + - Fix sorting in a frame with a list of columns which contains datetime64[ns] dtypes (GH3461_) .. _GH3164: https://github.com/pydata/pandas/issues/3164 .. _GH3251: https://github.com/pydata/pandas/issues/3251 @@ -64,6 +65,7 @@ pandas 0.12.0 .. _GH3437: https://github.com/pydata/pandas/issues/3437 .. _GH3455: https://github.com/pydata/pandas/issues/3455 .. _GH3457: https://github.com/pydata/pandas/issues/3457 +.. _GH3461: https://github.com/pydata/pandas/issues/3461 .. _GH3448: https://github.com/pydata/pandas/issues/3448 .. _GH3449: https://github.com/pydata/pandas/issues/3449 diff --git a/pandas/core/common.py b/pandas/core/common.py index 3edd7abcfc100..aa5205b674df3 100644 --- a/pandas/core/common.py +++ b/pandas/core/common.py @@ -1477,6 +1477,8 @@ def is_timedelta64_dtype(arr_or_dtype): tipo = arr_or_dtype.dtype.type return issubclass(tipo, np.timedelta64) +def needs_i8_conversion(arr_or_dtype): + return is_datetime64_dtype(arr_or_dtype) or is_timedelta64_dtype(arr_or_dtype) def is_float_dtype(arr_or_dtype): if isinstance(arr_or_dtype, np.dtype): diff --git a/pandas/core/frame.py b/pandas/core/frame.py index 69e7e4178ecfd..977dc9e2b56ff 100644 --- a/pandas/core/frame.py +++ b/pandas/core/frame.py @@ -3144,7 +3144,12 @@ def sort_index(self, axis=0, by=None, ascending=True, inplace=False): % str(x)) keys.append(k) - keys = [self[x].values for x in by] + def trans(v): + if com.needs_i8_conversion(v): + return v.view('i8') + return v + + keys = [trans(self[x].values) for x in by] indexer = _lexsort_indexer(keys, orders=ascending) indexer = com._ensure_platform_int(indexer) else: diff --git a/pandas/tests/test_frame.py b/pandas/tests/test_frame.py index 530128a100d0b..7bafed216b9b9 100644 --- a/pandas/tests/test_frame.py +++ b/pandas/tests/test_frame.py @@ -7737,6 +7737,25 @@ def test_sort_index_duplicates(self): except Exception, e: self.assertTrue('duplicate' in str(e)) + def test_sort_datetimes(self): + + # GH 3461, argsort / lexsort differences for a datetime column + df = DataFrame(['a','a','a','b','c','d','e','f','g'], + columns=['A'], + index=date_range('20130101',periods=9)) + dts = [ Timestamp(x) for x in ['2004-02-11','2004-01-21','2004-01-26','2005-09-20','2010-10-04','2009-05-12','2008-11-12','2010-09-28','2010-09-28'] ] + df['B'] = dts[::2] + dts[1::2] + df['C'] = 2. + df['A1'] = 3. + + df1 = df.sort(columns='A') + df2 = df.sort(columns=['A']) + assert_frame_equal(df1,df2) + + df1 = df.sort(columns='B') + df2 = df.sort(columns=['B']) + assert_frame_equal(df1,df2) + def test_frame_column_inplace_sort_exception(self): s = self.frame['A'] self.assertRaises(Exception, s.sort)