diff --git a/pandas/tools/tests/test_tile.py b/pandas/tools/tests/test_tile.py index 33d2a01b1256e..c9a96d80f35ba 100644 --- a/pandas/tools/tests/test_tile.py +++ b/pandas/tools/tests/test_tile.py @@ -12,7 +12,7 @@ from pandas.core.algorithms import quantile from pandas.tools.tile import cut, qcut import pandas.tools.tile as tmod -from pandas import to_datetime, DatetimeIndex +from pandas import to_datetime, DatetimeIndex, Timestamp class TestCut(tm.TestCase): @@ -313,6 +313,26 @@ def test_datetime_cut(self): result, bins = cut(data, 3, retbins=True) tm.assert_series_equal(Series(result), expected) + def test_datetime_bin(self): + data = [np.datetime64('2012-12-13'), np.datetime64('2012-12-15')] + bin_data = ['2012-12-12', '2012-12-14', '2012-12-16'] + expected = Series(['(2012-12-12 00:00:00, 2012-12-14 00:00:00]', + '(2012-12-14 00:00:00, 2012-12-16 00:00:00]'], + ).astype("category", ordered=True) + + for conv in [Timestamp, Timestamp, np.datetime64]: + bins = [conv(v) for v in bin_data] + result = cut(data, bins=bins) + tm.assert_series_equal(Series(result), expected) + + bin_pydatetime = [Timestamp(v).to_pydatetime() for v in bin_data] + result = cut(data, bins=bin_pydatetime) + tm.assert_series_equal(Series(result), expected) + + bins = to_datetime(bin_data) + result = cut(data, bins=bin_pydatetime) + tm.assert_series_equal(Series(result), expected) + def curpath(): pth, _ = os.path.split(os.path.abspath(__file__)) diff --git a/pandas/tools/tile.py b/pandas/tools/tile.py index f62bac9e951a7..a372e113f1d7e 100644 --- a/pandas/tools/tile.py +++ b/pandas/tools/tile.py @@ -13,6 +13,7 @@ from pandas.compat import zip from pandas import to_timedelta, to_datetime from pandas.types.common import is_datetime64_dtype, is_timedelta64_dtype +from pandas.lib import infer_dtype import numpy as np @@ -116,6 +117,7 @@ def cut(x, bins, right=True, labels=None, retbins=False, precision=3, else: bins = np.asarray(bins) + bins = _convert_bin_to_numeric_type(bins) if (np.diff(bins) < 0).any(): raise ValueError('bins must increase monotonically.') @@ -327,6 +329,19 @@ def _coerce_to_type(x): return x, dtype +def _convert_bin_to_numeric_type(x): + """ + if the passed bin is of datetime/timedelta type, + this method converts it to integer + """ + dtype = infer_dtype(x) + if dtype == 'timedelta' or dtype == 'timedelta64': + x = to_timedelta(x).view(np.int64) + elif dtype == 'datetime' or dtype == 'datetime64': + x = to_datetime(x).view(np.int64) + return x + + def _preprocess_for_cut(x): """ handles preprocessing for cut where we convert passed