7
7
from scipy import interpolate
8
8
from scipy .stats import spearmanr
9
9
from .base import BaseEstimator , TransformerMixin , RegressorMixin
10
- from .utils import as_float_array , check_array , check_consistent_length
10
+ from .utils import as_float_array , check_array , check_consistent_length , deprecated
11
11
from .utils .fixes import astype
12
12
from ._isotonic import _isotonic_regression , _make_unique
13
13
import warnings
@@ -234,6 +234,32 @@ def __init__(self, y_min=None, y_max=None, increasing=True,
234
234
self .increasing = increasing
235
235
self .out_of_bounds = out_of_bounds
236
236
237
+ @property
238
+ @deprecated ("Attribute ``X_`` is deprecated in version 0.18 and will be removed in version 0.20." )
239
+ def X_ (self ):
240
+ return self ._X_
241
+
242
+ @X_ .setter
243
+ def X_ (self , value ):
244
+ self ._X_ = value
245
+
246
+ @X_ .deleter
247
+ def X_ (self ):
248
+ del self ._X_
249
+
250
+ @property
251
+ @deprecated ("Attribute ``y_`` is deprecated in version 0.18 and will be removed in version 0.20." )
252
+ def y_ (self ):
253
+ return self ._y_
254
+
255
+ @y_ .setter
256
+ def y_ (self , value ):
257
+ self ._y_ = value
258
+
259
+ @y_ .deleter
260
+ def y_ (self ):
261
+ del self ._y_
262
+
237
263
def _check_fit_data (self , X , y , sample_weight = None ):
238
264
if len (X .shape ) != 1 :
239
265
raise ValueError ("X should be a 1d array" )
@@ -252,7 +278,7 @@ def _build_f(self, X, y):
252
278
# single y, constant prediction
253
279
self .f_ = lambda x : y .repeat (x .shape )
254
280
else :
255
- self .f_ = interpolate .interp1d (X , y , kind = 'slinear ' ,
281
+ self .f_ = interpolate .interp1d (X , y , kind = 'linear ' ,
256
282
bounds_error = bounds_error )
257
283
258
284
def _build_y (self , X , y , sample_weight ):
@@ -282,8 +308,8 @@ def _build_y(self, X, y, sample_weight):
282
308
X , y , sample_weight = [astype (array [order ], np .float64 , copy = False )
283
309
for array in [X , y , sample_weight ]]
284
310
unique_X , unique_y , unique_sample_weight = _make_unique (X , y , sample_weight )
285
- self .X_ = unique_X
286
- self .y_ = isotonic_regression (unique_y , unique_sample_weight , self .y_min ,
311
+ self ._X_ = unique_X
312
+ self ._y_ = isotonic_regression (unique_y , unique_sample_weight , self .y_min ,
287
313
self .y_max , increasing = self .increasing_ )
288
314
289
315
return order_inv
@@ -317,11 +343,24 @@ def fit(self, X, y, sample_weight=None):
317
343
self ._build_y (X , y , sample_weight )
318
344
319
345
# Handle the left and right bounds on X
320
- self .X_min_ = np .min (self .X_ )
321
- self .X_max_ = np .max (self .X_ )
346
+ self .X_min_ = np .min (self ._X_ )
347
+ self .X_max_ = np .max (self ._X_ )
348
+
349
+ # Remove unnecessary points for faster prediction
350
+ keep_data = np .ones ((len (self ._y_ ),), dtype = bool )
351
+ # Aside from the 1st and last point, remove points whose y values
352
+ # are equal to both the point before and the point after it.
353
+ keep_data [1 :- 1 ] = np .logical_or (
354
+ np .not_equal (self ._y_ [1 :- 1 ], self ._y_ [:- 2 ]),
355
+ np .not_equal (self ._y_ [1 :- 1 ], self ._y_ [2 :])
356
+ )
357
+ # We're keeping self.X_ and self.y_ around for backwards compatibility,
358
+ # but they should be considered deprecated.
359
+ self ._necessary_X_ = self ._X_ [keep_data ]
360
+ self ._necessary_y_ = self ._y_ [keep_data ]
322
361
323
362
# Build f_
324
- self ._build_f (self .X_ , self .y_ )
363
+ self ._build_f (self ._necessary_X_ , self ._necessary_y_ )
325
364
326
365
return self
327
366
@@ -381,4 +420,4 @@ def __setstate__(self, state):
381
420
We need to rebuild the interpolation function.
382
421
"""
383
422
self .__dict__ .update (state )
384
- self ._build_f (self .X_ , self .y_ )
423
+ self ._build_f (self ._necessary_X_ , self ._necessary_y_ )
0 commit comments