Skip to content

Commit 9939d63

Browse files
cleaned up fill values our of borders
1 parent 06fa995 commit 9939d63

File tree

2 files changed

+30
-45
lines changed

2 files changed

+30
-45
lines changed

climada/util/interpolation.py

Lines changed: 17 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -37,8 +37,8 @@ def interpolate_ev(
3737
logy = False,
3838
x_threshold = None,
3939
y_threshold = None,
40-
y_asymptotic = np.nan,
41-
fill_value = np.nan
40+
extrapolation = False,
41+
y_asymptotic = np.nan
4242
):
4343
"""
4444
Util function to interpolate (and extrapolate) training data (x_train, y_train)
@@ -60,16 +60,14 @@ def interpolate_ev(
6060
Lower threshold to filter x_train. Defaults to None.
6161
y_threshold : float, optional
6262
Lower threshold to filter y_train. Defaults to None.
63+
extrapolation : bool, optional
64+
If set to True, values will be extrapolated. If set to False, x_test values
65+
smaller than x_train will be assigned y_train[0] (x_train must be sorted in
66+
ascending order), and x_test values larger than x_train will be assigned
67+
y_asymptotic. Defaults to False
6368
y_asymptotic : float, optional
64-
Return value if x_test > x_train and if
65-
x_train.size < 2. Defaults to np.nan.
66-
fill_value : tuple, float, str
67-
fill values to use when x_test outside of range of x_train.
68-
If set to "extrapolate", values will be extrapolated. If set to a float, value will
69-
be used on both sides. If set to tuple, left value will be used for left side and
70-
right value will be used for right side. If tuple and left value is "maximum",
71-
the maximum of the cummulative frequencies will be used to compute exceedance
72-
intensities on the left. Defaults to np.nan
69+
Return value and if extrapolation is True or x_train.size < 2, for x_test
70+
values larger than x_train. Defaults to np.nan.
7371
7472
Returns
7573
-------
@@ -88,23 +86,14 @@ def interpolate_ev(
8886
return _interpolate_small_input(x_test, x_train, y_train, logy, y_asymptotic)
8987

9088
# calculate fill values
91-
if isinstance(fill_value, tuple):
92-
if fill_value[0] == 'maximum':
93-
fill_value = (
94-
np.max(y_train),
95-
np.log10(fill_value[1]) if logy else fill_value[1]
96-
)
97-
elif logy:
98-
fill_value = tuple(np.log10(fill_value))
99-
elif isinstance(fill_value, (float, int)) and logy:
100-
fill_value = np.log10(fill_value)
101-
102-
# warn if data is being extrapolated
103-
if (
104-
fill_value == 'extrapolate' and
105-
((np.min(x_test) < np.min(x_train)) or (np.max(x_test) > np.max(x_train)))
106-
):
107-
LOGGER.warning('Data is being extrapolated.')
89+
if extrapolation:
90+
fill_value = 'extrapolate'
91+
if np.min(x_test) < np.min(x_train) or np.max(x_test) > np.max(x_train):
92+
LOGGER.warning('Data is being extrapolated.')
93+
else:
94+
if not all(sorted(x_train) == x_train):
95+
raise ValueError('x_train array must be sorted in ascending order.')
96+
fill_value = (y_train[0], np.log10(y_asymptotic) if logy else y_asymptotic)
10897

10998
interpolation = interpolate.interp1d(
11099
x_train, y_train, fill_value=fill_value, bounds_error=False)

climada/util/test/test_interpolation.py

Lines changed: 13 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,15 @@ class TestFitMethods(unittest.TestCase):
3131
def test_interpolate_ev_linear_interp(self):
3232
"""Test linear interpolation"""
3333
x_train = np.array([1., 3., 5.])
34-
y_train = np.array([2., 4., 8.])
35-
x_test = np.array([0., 3., 4.])
34+
y_train = np.array([8., 4., 2.])
35+
x_test = np.array([0., 3., 4., 6.])
3636
np.testing.assert_allclose(
3737
interpolate_ev(x_test, x_train, y_train),
38-
np.array([np.nan, 4., 6.])
38+
np.array([8., 4., 3., np.nan])
3939
)
4040
np.testing.assert_allclose(
41-
interpolate_ev(x_test, x_train, y_train, fill_value = -1),
42-
np.array([-1., 4., 6.])
41+
interpolate_ev(x_test, x_train, y_train, y_asymptotic = 0),
42+
np.array([8., 4., 3., 0.])
4343
)
4444

4545
def test_interpolate_ev_threshold_parameters(self):
@@ -49,15 +49,15 @@ def test_interpolate_ev_threshold_parameters(self):
4949
x_test = np.array([-1., 3., 4.])
5050
np.testing.assert_allclose(
5151
interpolate_ev(x_test, x_train, y_train),
52-
np.array([np.nan, 1., 2.])
52+
np.array([4., 1., 2.])
5353
)
5454
np.testing.assert_allclose(
5555
interpolate_ev(x_test, x_train, y_train, x_threshold=1.),
56-
np.array([np.nan, 1., 2.])
56+
np.array([1., 1., 2.])
5757
)
5858
np.testing.assert_allclose(
5959
interpolate_ev(x_test, x_train, y_train, y_threshold=2.),
60-
np.array([np.nan, 4., 4.])
60+
np.array([4., 4., 4.])
6161
)
6262

6363
def test_interpolate_ev_scale_parameters(self):
@@ -66,29 +66,25 @@ def test_interpolate_ev_scale_parameters(self):
6666
y_train = np.array([1., 3.])
6767
x_test = np.array([1e0, 1e2])
6868
np.testing.assert_allclose(
69-
interpolate_ev(x_test, x_train, y_train, logx=True, fill_value='extrapolate'),
69+
interpolate_ev(x_test, x_train, y_train, logx=True, extrapolation=True),
7070
np.array([0., 2.])
7171
)
7272
np.testing.assert_allclose(
7373
interpolate_ev(x_test, x_train, y_train, logx=True),
74-
np.array([np.nan, 2.])
74+
np.array([1., 2.])
7575
)
7676
x_train = np.array([1., 3.])
7777
y_train = np.array([1e1, 1e3])
7878
x_test = np.array([0., 2.])
7979
np.testing.assert_allclose(
80-
interpolate_ev(x_test, x_train, y_train, logy=True, fill_value='extrapolate'),
80+
interpolate_ev(x_test, x_train, y_train, logy=True, extrapolation=True),
8181
np.array([1e0, 1e2])
8282
)
83-
np.testing.assert_allclose(
84-
interpolate_ev(x_test, x_train, y_train, logy=True),
85-
np.array([np.nan, 1e2])
86-
)
8783
x_train = np.array([1e1, 1e3])
8884
y_train = np.array([1e1, 1e5])
8985
x_test = np.array([1e0, 1e2])
9086
np.testing.assert_allclose(
91-
interpolate_ev(x_test, x_train, y_train, logx=True, logy=True, fill_value='extrapolate'),
87+
interpolate_ev(x_test, x_train, y_train, logx=True, logy=True, extrapolation=True),
9288
np.array([1e-1, 1e3])
9389
)
9490

@@ -99,7 +95,7 @@ def test_interpolate_ev_degenerate_input(self):
9995
y_train = np.zeros(3)
10096
np.testing.assert_allclose(
10197
interpolate_ev(x_test, x_train, y_train),
102-
np.array([np.nan, 0., 0.])
98+
np.array([0., 0., 0.])
10399
)
104100

105101
def test_interpolate_ev_small_input(self):

0 commit comments

Comments
 (0)