Skip to content

Commit 688aabe

Browse files
add reverse kwarg to change ordering
1 parent cb38e22 commit 688aabe

4 files changed

Lines changed: 214 additions & 34 deletions

File tree

climada/hazard/base.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -485,6 +485,7 @@ def local_exceedance_intensity(
485485
log_frequency=True,
486486
log_intensity=True,
487487
bin_decimals=None,
488+
reverse=False,
488489
):
489490
"""Compute local exceedance intensity for given return periods. The default method
490491
is fitting the ordered intensitites per centroid to the corresponding cummulated
@@ -519,6 +520,9 @@ def local_exceedance_intensity(
519520
Number of decimals to group and bin intensity values. Binning results in smoother (and
520521
coarser) interpolation and more stable extrapolation. For more details and sensible
521522
values for bin_decimals, see Notes. If None, values are not binned. Defaults to None.
523+
reverse : bool, optional
524+
If set to True, intensities are sorted in reverse order (larger intensity means
525+
less impact). Defaults to False.
522526
523527
Returns
524528
-------
@@ -577,6 +581,7 @@ def local_exceedance_intensity(
577581
method=method,
578582
y_asymptotic=0.0,
579583
bin_decimals=bin_decimals,
584+
reverse=reverse,
580585
)
581586
for i_centroid in nonzero_centroids
582587
]
@@ -627,6 +632,7 @@ def local_return_period(
627632
log_frequency=True,
628633
log_intensity=True,
629634
bin_decimals=None,
635+
reverse=False,
630636
):
631637
"""Compute local return periods for given hazard intensities. The default method
632638
is fitting the ordered intensitites per centroid to the corresponding cummulated
@@ -662,6 +668,9 @@ def local_return_period(
662668
Number of decimals to group and bin intensity values. Binning results in smoother (and
663669
coarser) interpolation and more stable extrapolation. For more details and sensible
664670
values for bin_decimals, see Notes. If None, values are not binned. Defaults to None.
671+
reverse : bool, optional
672+
If set to True, intensities are sorted in reverse order (larger intensity means
673+
less impact). Defaults to False.
665674
666675
667676
Returns
@@ -718,6 +727,7 @@ def local_return_period(
718727
method=method,
719728
y_asymptotic=np.nan,
720729
bin_decimals=bin_decimals,
730+
reverse=reverse,
721731
)
722732
for i_centroid in nonzero_centroids
723733
]

climada/util/interpolation.py

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ def preprocess_and_interpolate_ev(
3939
method="interpolate",
4040
y_asymptotic=np.nan,
4141
bin_decimals=None,
42+
reverse=False,
4243
):
4344
"""Function to first preprocess (frequency, values) data (if extrapolating, one can bin the
4445
data according to their value, see Notes), compute the cumulative frequencies, and then
@@ -81,6 +82,9 @@ def preprocess_and_interpolate_ev(
8182
Number of decimals to group and bin the values. Binning results in smoother (and coarser)
8283
interpolation and more stable extrapolation. For more details and sensible values for
8384
bin_decimals, see Notes. If None, values are not binned. Defaults to None.
85+
reverse : bool, optional
86+
If set to True, values are sorted in reverse order (i.e., larger values means
87+
less impact). Defaults to False.
8488
8589
Returns
8690
-------
@@ -129,9 +133,12 @@ def preprocess_and_interpolate_ev(
129133
values = np.squeeze(values[sorted_idxs])
130134
frequency = frequency[sorted_idxs]
131135

136+
if reverse:
137+
values, frequency = (values[::-1], frequency[::-1])
138+
132139
# group similar values together
133140
if isinstance(bin_decimals, int):
134-
frequency, values = _group_frequency(frequency, values, bin_decimals)
141+
frequency, values = _group_frequency(frequency, values, bin_decimals, reverse)
135142

136143
# transform frequencies to cummulative frequencies
137144
frequency = np.cumsum(frequency[::-1])[::-1]
@@ -362,7 +369,7 @@ def _interpolate_small_input(x_test, x_train, y_train, logy, y_asymptotic):
362369
return y_test
363370

364371

365-
def _group_frequency(frequency, value, bin_decimals):
372+
def _group_frequency(frequency, value, bin_decimals, reverse=False):
366373
"""
367374
Util function to aggregate (add) frequencies for equal values
368375
@@ -375,6 +382,8 @@ def _group_frequency(frequency, value, bin_decimals):
375382
bin_decimals : int
376383
decimals according to which values are binned and their corresponding frequency are
377384
grouped.
385+
reverse: bool, optional
386+
if frequencies should be summed in reverse order. Defaults to False.
378387
379388
Returns
380389
-------
@@ -385,7 +394,8 @@ def _group_frequency(frequency, value, bin_decimals):
385394
frequency, value = np.array(frequency), np.array(value)
386395
if frequency.size == 0 and value.size == 0:
387396
return ([], [])
388-
397+
if reverse:
398+
frequency, value = (frequency[::-1], value[::-1])
389399
# round values and group them
390400
value = np.around(value, decimals=bin_decimals)
391401
value_unique, start_indices = np.unique(value, return_index=True)
@@ -402,6 +412,7 @@ def _group_frequency(frequency, value, bin_decimals):
402412
# add frequency for equal value
403413
start_indices = np.insert(start_indices, value_unique.size, frequency.size)
404414
frequency = np.add.reduceat(frequency, start_indices[:-1])
405-
return frequency, value_unique
406-
415+
value = value_unique
416+
if reverse:
417+
frequency, value = (frequency[::-1], value[::-1])
407418
return frequency, value

climada/util/test/test_interpolation.py

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -282,6 +282,14 @@ def test_preprocess_and_interpolate_ev(self):
282282
with self.assertRaises(ValueError):
283283
u_interp.preprocess_and_interpolate_ev(None, None, frequency, values)
284284

285+
# test negative values
286+
np.testing.assert_allclose(
287+
[np.nan, -55.0, np.nan],
288+
u_interp.preprocess_and_interpolate_ev(
289+
test_frequency, None, frequency, -1 * values, reverse=True
290+
),
291+
)
292+
285293

286294
# Execute Tests
287295
if __name__ == "__main__":

0 commit comments

Comments
 (0)