@@ -229,7 +229,7 @@ def skips_nulls(self):
229
229
230
230
231
231
class CutOp (WindowOp ):
232
- def __init__ (self , bins : typing .Union [int , pd .IntervalIndex ]):
232
+ def __init__ (self , bins : typing .Union [int , pd .IntervalIndex ], labels = None ):
233
233
if isinstance (bins , int ):
234
234
if not bins > 0 :
235
235
raise ValueError ("`bins` should be a positive integer." )
@@ -239,6 +239,8 @@ def __init__(self, bins: typing.Union[int, pd.IntervalIndex]):
239
239
self ._bins_int = 0
240
240
self ._bins = bins
241
241
242
+ self ._labels = labels
243
+
242
244
def _as_ibis (self , x : ibis_types .Column , window = None ):
243
245
out = ibis .case ()
244
246
@@ -247,12 +249,37 @@ def _as_ibis(self, x: ibis_types.Column, window=None):
247
249
col_max = _apply_window_if_present (x .max (), window )
248
250
bin_width = (col_max - col_min ) / self ._bins
249
251
250
- for this_bin in range (self ._bins_int - 1 ):
251
- out = out .when (
252
- x <= (col_min + (this_bin + 1 ) * bin_width ),
253
- dtypes .literal_to_ibis_scalar (this_bin , force_dtype = Int64Dtype ()),
254
- )
255
- out = out .when (x .notnull (), self ._bins - 1 )
252
+ if self ._labels is False :
253
+ for this_bin in range (self ._bins_int - 1 ):
254
+ out = out .when (
255
+ x <= (col_min + (this_bin + 1 ) * bin_width ),
256
+ dtypes .literal_to_ibis_scalar (
257
+ this_bin , force_dtype = Int64Dtype ()
258
+ ),
259
+ )
260
+ out = out .when (x .notnull (), self ._bins - 1 )
261
+ else :
262
+ interval_struct = None
263
+ adj = (col_max - col_min ) * 0.001
264
+ for this_bin in range (self ._bins_int ):
265
+ left_edge = (
266
+ col_min + this_bin * bin_width - (0 if this_bin > 0 else adj )
267
+ )
268
+ right_edge = col_min + (this_bin + 1 ) * bin_width
269
+ interval_struct = ibis .struct (
270
+ {
271
+ "left_exclusive" : left_edge ,
272
+ "right_inclusive" : right_edge ,
273
+ }
274
+ )
275
+
276
+ if this_bin < self ._bins_int - 1 :
277
+ out = out .when (
278
+ x <= (col_min + (this_bin + 1 ) * bin_width ),
279
+ interval_struct ,
280
+ )
281
+ else :
282
+ out = out .when (x .notnull (), interval_struct )
256
283
else :
257
284
for interval in self ._bins :
258
285
condition = (x > interval .left ) & (x <= interval .right )
0 commit comments