11
11
import pandas .core .algorithms as algos
12
12
import pandas .core .nanops as nanops
13
13
from pandas .compat import zip
14
-
14
+ from pandas .tseries .timedeltas import to_timedelta
15
+ from pandas .types .common import (needs_i8_conversion )
15
16
import numpy as np
16
17
17
18
@@ -81,6 +82,13 @@ def cut(x, bins, right=True, labels=None, retbins=False, precision=3,
81
82
array([1, 1, 1, 1, 1], dtype=int64)
82
83
"""
83
84
# NOTE: this binning code is changed a bit from histogram for var(x) == 0
85
+ # for handling the cut for datetime and timedelta objects
86
+ if needs_i8_conversion (x ):
87
+ x = x .values .view ('i8' )
88
+ time_data = True
89
+ else :
90
+ time_data = False
91
+
84
92
if not np .iterable (bins ):
85
93
if is_scalar (bins ) and bins < 1 :
86
94
raise ValueError ("`bins` should be a positive integer." )
@@ -116,7 +124,7 @@ def cut(x, bins, right=True, labels=None, retbins=False, precision=3,
116
124
117
125
return _bins_to_cuts (x , bins , right = right , labels = labels ,
118
126
retbins = retbins , precision = precision ,
119
- include_lowest = include_lowest )
127
+ include_lowest = include_lowest , time_data = time_data )
120
128
121
129
122
130
def qcut (x , q , labels = None , retbins = False , precision = 3 ):
@@ -176,7 +184,8 @@ def qcut(x, q, labels=None, retbins=False, precision=3):
176
184
177
185
178
186
def _bins_to_cuts (x , bins , right = True , labels = None , retbins = False ,
179
- precision = 3 , name = None , include_lowest = False ):
187
+ precision = 3 , name = None , include_lowest = False ,
188
+ time_data = False ):
180
189
x_is_series = isinstance (x , Series )
181
190
series_index = None
182
191
@@ -205,7 +214,8 @@ def _bins_to_cuts(x, bins, right=True, labels=None, retbins=False,
205
214
while True :
206
215
try :
207
216
levels = _format_levels (bins , precision , right = right ,
208
- include_lowest = include_lowest )
217
+ include_lowest = include_lowest ,
218
+ time_data = time_data )
209
219
except ValueError :
210
220
increases += 1
211
221
precision += 1
@@ -239,7 +249,7 @@ def _bins_to_cuts(x, bins, right=True, labels=None, retbins=False,
239
249
240
250
241
251
def _format_levels (bins , prec , right = True ,
242
- include_lowest = False ):
252
+ include_lowest = False , time_data = False ):
243
253
fmt = lambda v : _format_label (v , precision = prec )
244
254
if right :
245
255
levels = []
@@ -249,16 +259,24 @@ def _format_levels(bins, prec, right=True,
249
259
if a != b and fa == fb :
250
260
raise ValueError ('precision too low' )
251
261
252
- formatted = '(%s, %s]' % (fa , fb )
262
+ if time_data :
263
+ formatted = '(%s, %s]' % (to_timedelta (float (fa ), unit = 'ns' ),
264
+ to_timedelta (float (fb ), unit = 'ns' ))
265
+ else :
266
+ formatted = '(%s, %s]' % (fa , fb )
253
267
254
268
levels .append (formatted )
255
269
256
270
if include_lowest :
257
271
levels [0 ] = '[' + levels [0 ][1 :]
258
272
else :
259
- levels = ['[%s, %s)' % (fmt (a ), fmt (b ))
260
- for a , b in zip (bins , bins [1 :])]
261
-
273
+ if time_data :
274
+ levels = ['[%s, %s)' % (to_timedelta (float (fmt (fa )), unit = 'ns' ),
275
+ to_timedelta (float (fmt (b )), unit = 'ns' ))
276
+ for a , b in zip (bins , bins [1 :])]
277
+ else :
278
+ levels = ['[%s, %s)' % (fmt (a ), fmt (b ))
279
+ for a , b in zip (bins , bins [1 :])]
262
280
return levels
263
281
264
282
0 commit comments