37
37
from pandas .core .dtypes .generic import ABCSeries
38
38
from pandas .core .dtypes .missing import isna
39
39
40
+ from pandas .core import accessor
40
41
from pandas .core .algorithms import take_1d
41
42
from pandas .core .arrays .interval import IntervalArray , _interval_shared_docs
42
43
import pandas .core .common as com
@@ -181,7 +182,28 @@ def func(intvidx_self, other, sort=False):
181
182
),
182
183
)
183
184
)
184
- class IntervalIndex (IntervalMixin , Index ):
185
+ @accessor .delegate_names (
186
+ delegate = IntervalArray ,
187
+ accessors = [
188
+ "_ndarray_values" ,
189
+ "length" ,
190
+ "size" ,
191
+ "left" ,
192
+ "right" ,
193
+ "mid" ,
194
+ "closed" ,
195
+ "dtype" ,
196
+ ],
197
+ typ = "property" ,
198
+ overwrite = True ,
199
+ )
200
+ @accessor .delegate_names (
201
+ delegate = IntervalArray ,
202
+ accessors = ["__array__" , "overlaps" , "contains" ],
203
+ typ = "method" ,
204
+ overwrite = True ,
205
+ )
206
+ class IntervalIndex (IntervalMixin , Index , accessor .PandasDelegate ):
185
207
_typ = "intervalindex"
186
208
_comparables = ["name" ]
187
209
_attributes = ["name" , "closed" ]
@@ -192,6 +214,8 @@ class IntervalIndex(IntervalMixin, Index):
192
214
# Immutable, so we are able to cache computations like isna in '_mask'
193
215
_mask = None
194
216
217
+ _raw_inherit = {"_ndarray_values" , "__array__" , "overlaps" , "contains" }
218
+
195
219
# --------------------------------------------------------------------
196
220
# Constructors
197
221
@@ -388,30 +412,6 @@ def to_tuples(self, na_tuple=True):
388
412
def _multiindex (self ):
389
413
return MultiIndex .from_arrays ([self .left , self .right ], names = ["left" , "right" ])
390
414
391
- @property
392
- def left (self ):
393
- """
394
- Return the left endpoints of each Interval in the IntervalIndex as
395
- an Index.
396
- """
397
- return self ._data ._left
398
-
399
- @property
400
- def right (self ):
401
- """
402
- Return the right endpoints of each Interval in the IntervalIndex as
403
- an Index.
404
- """
405
- return self ._data ._right
406
-
407
- @property
408
- def closed (self ):
409
- """
410
- Whether the intervals are closed on the left-side, right-side, both or
411
- neither.
412
- """
413
- return self ._data ._closed
414
-
415
415
@Appender (
416
416
_interval_shared_docs ["set_closed" ]
417
417
% dict (
@@ -434,25 +434,8 @@ def closed(self):
434
434
)
435
435
)
436
436
def set_closed (self , closed ):
437
- if closed not in _VALID_CLOSED :
438
- raise ValueError (f"invalid option for 'closed': { closed } " )
439
-
440
- # return self._shallow_copy(closed=closed)
441
437
array = self ._data .set_closed (closed )
442
- return self ._simple_new (array , self .name )
443
-
444
- @property
445
- def length (self ):
446
- """
447
- Return an Index with entries denoting the length of each Interval in
448
- the IntervalIndex.
449
- """
450
- return self ._data .length
451
-
452
- @property
453
- def size (self ):
454
- # Avoid materializing ndarray[Interval]
455
- return self ._data .size
438
+ return self ._simple_new (array , self .name ) # TODO: can we use _shallow_copy?
456
439
457
440
def __len__ (self ) -> int :
458
441
return len (self .left )
@@ -468,16 +451,6 @@ def values(self):
468
451
def _values (self ):
469
452
return self ._data
470
453
471
- @cache_readonly
472
- def _ndarray_values (self ) -> np .ndarray :
473
- return np .array (self ._data )
474
-
475
- def __array__ (self , result = None ):
476
- """
477
- The array interface, return my values.
478
- """
479
- return self ._ndarray_values
480
-
481
454
def __array_wrap__ (self , result , context = None ):
482
455
# we don't want the superclass implementation
483
456
return result
@@ -506,13 +479,6 @@ def astype(self, dtype, copy=True):
506
479
return self ._shallow_copy (new_values .left , new_values .right )
507
480
return super ().astype (dtype , copy = copy )
508
481
509
- @cache_readonly
510
- def dtype (self ):
511
- """
512
- Return the dtype object of the underlying data.
513
- """
514
- return self ._data .dtype
515
-
516
482
@property
517
483
def inferred_type (self ) -> str :
518
484
"""Return a string of the type inferred from the values"""
@@ -1177,44 +1143,6 @@ def equals(self, other) -> bool:
1177
1143
and self .closed == other .closed
1178
1144
)
1179
1145
1180
- @Appender (
1181
- _interval_shared_docs ["contains" ]
1182
- % dict (
1183
- klass = "IntervalIndex" ,
1184
- examples = textwrap .dedent (
1185
- """\
1186
- >>> intervals = pd.IntervalIndex.from_tuples([(0, 1), (1, 3), (2, 4)])
1187
- >>> intervals
1188
- IntervalIndex([(0, 1], (1, 3], (2, 4]],
1189
- closed='right',
1190
- dtype='interval[int64]')
1191
- >>> intervals.contains(0.5)
1192
- array([ True, False, False])
1193
- """
1194
- ),
1195
- )
1196
- )
1197
- def contains (self , other ):
1198
- return self ._data .contains (other )
1199
-
1200
- @Appender (
1201
- _interval_shared_docs ["overlaps" ]
1202
- % dict (
1203
- klass = "IntervalIndex" ,
1204
- examples = textwrap .dedent (
1205
- """\
1206
- >>> intervals = pd.IntervalIndex.from_tuples([(0, 1), (1, 3), (2, 4)])
1207
- >>> intervals
1208
- IntervalIndex([(0, 1], (1, 3], (2, 4]],
1209
- closed='right',
1210
- dtype='interval[int64]')
1211
- """
1212
- ),
1213
- )
1214
- )
1215
- def overlaps (self , other ):
1216
- return self ._data .overlaps (other )
1217
-
1218
1146
@Appender (_index_shared_docs ["intersection" ])
1219
1147
@SetopCheck (op_name = "intersection" )
1220
1148
def intersection (
@@ -1314,6 +1242,19 @@ def is_all_dates(self) -> bool:
1314
1242
1315
1243
# TODO: arithmetic operations
1316
1244
1245
+ def _delegate_property_get (self , name , * args , ** kwargs ):
1246
+ """ method delegation to the ._values """
1247
+ prop = getattr (self ._data , name )
1248
+ return prop # no wrapping for now
1249
+
1250
+ def _delegate_method (self , name , * args , ** kwargs ):
1251
+ """ method delegation to the ._data """
1252
+ method = getattr (self ._data , name )
1253
+ res = method (* args , ** kwargs )
1254
+ if is_scalar (res ) or name in self ._raw_inherit :
1255
+ return res
1256
+ return type (self )(res , name = self .name )
1257
+
1317
1258
1318
1259
IntervalIndex ._add_logical_methods_disabled ()
1319
1260
0 commit comments