From d2d7a84265094cd5c866feebaebefe03ee6ed9b9 Mon Sep 17 00:00:00 2001 From: Daniel Huppmann Date: Wed, 14 Sep 2022 19:08:19 +0200 Subject: [PATCH] Migrate `compute_bias()` to `compute` module (#702) --- RELEASE_NOTES.md | 1 + pyam/compute.py | 47 ++++++++++++++++++++++++++++++ pyam/core.py | 51 ++++----------------------------- pyam/units.py | 2 -- tests/test_feature_debiasing.py | 4 +-- 5 files changed, 55 insertions(+), 50 deletions(-) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index 6a4de3cba..2cf84afd5 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -7,6 +7,7 @@ dependency for better performance. ## Individual updates +- [#702](https://github.com/IAMconsortium/pyam/pull/702) Migrate `compute_bias()` to `compute` module - [#701](https://github.com/IAMconsortium/pyam/pull/701) Add **xlsxwriter** as dependency to improve `to_excel()` performance - [#699](https://github.com/IAMconsortium/pyam/pull/699) Add filter options to IIASA API `index()`, `meta()` and `properties()` methods - [#697](https://github.com/IAMconsortium/pyam/pull/697) Add warning if IIASA API returns empty result diff --git a/pyam/compute.py b/pyam/compute.py index dee80d268..be7989d61 100644 --- a/pyam/compute.py +++ b/pyam/compute.py @@ -2,6 +2,7 @@ import pandas as pd from pyam.index import replace_index_values from pyam.timeseries import growth_rate +from pyam._debiasing import _compute_bias from pyam.utils import remove_from_list @@ -113,6 +114,52 @@ def learning_rate(self, name, performance, experience, append=False): return self._df._finalize(value, append=append, variable=name, unit="") + def bias(self, name, method, axis): + """Compute the bias weights and add to 'meta' + + Parameters + ---------- + name : str + Column name in the 'meta' dataframe + method : str + Method to compute the bias weights, see the notes + axis : str + Index dimensions on which to apply the `method` + + Notes + ----- + + The following methods are implemented: + + - "count": use the inverse of the number of scenarios grouped by `axis` names. + + Using the following method on an IamDataFrame with three scenarios + + .. code-block:: python + + df.compute.bias(name="bias-weight", method="count", axis="scenario") + + results in the following column to be added to *df.meta*: + + .. list-table:: + :header-rows: 1 + + * - model + - scenario + - bias-weight + * - model_a + - scen_a + - 0.5 + * - model_a + - scen_b + - 1 + * - model_b + - scen_a + - 0.5 + + """ + _compute_bias(self._df, name, method, axis) + def _compute_learning_rate(x, performance, experience): """Internal implementation for computing implicit learning rate from timeseries data diff --git a/pyam/core.py b/pyam/core.py index bd03f0838..329966803 100755 --- a/pyam/core.py +++ b/pyam/core.py @@ -77,8 +77,7 @@ replace_index_values, ) from pyam.time import swap_time_for_year, swap_year_for_time -from pyam._debiasing import _compute_bias -from pyam.logging import raise_data_error +from pyam.logging import raise_data_error, deprecation_warning logger = logging.getLogger(__name__) @@ -1012,50 +1011,10 @@ def validate(self, criteria={}, exclude_on_fail=False): return df.reset_index() def compute_bias(self, name, method, axis): - """Compute the bias weights and add to 'meta' - - Parameters - ---------- - name : str - Column name in the 'meta' dataframe - method : str - Method to compute the bias weights, see the notes - axis : str - Index dimensions on which to apply the `method` - - Notes - ----- - - The following methods are implemented: - - - "count": use the inverse of the number of scenarios grouped by `axis` names. - - Using the following method on an IamDataFrame with three scenarios - - .. code-block:: python - - df.compute_bias(name="bias-weight", method="count", axis="scenario") - - results in the following column to be added to *df.meta*: - - .. list-table:: - :header-rows: 1 - - * - model - - scenario - - bias-weight - * - model_a - - scen_a - - 0.5 - * - model_a - - scen_b - - 1 - * - model_b - - scen_a - - 0.5 - - """ - _compute_bias(self, name, method, axis) + """DEPRECATED - please use :meth:`IamDataFrame.compute.bias()`""" + # TODO: deprecated, remove for release >= 1.7 + deprecation_warning("Use `df.compute.bias()` instead.") + self.compute.bias(name, method, axis) def rename( self, mapping=None, inplace=False, append=False, check_duplicates=True, **kwargs diff --git a/pyam/units.py b/pyam/units.py index 3e5ac2ded..18a5a1e29 100644 --- a/pyam/units.py +++ b/pyam/units.py @@ -3,8 +3,6 @@ import iam_units import pint - -from pyam.logging import deprecation_warning from pyam.index import replace_index_values logger = logging.getLogger(__name__) diff --git a/tests/test_feature_debiasing.py b/tests/test_feature_debiasing.py index 590eac91e..9f045dadf 100644 --- a/tests/test_feature_debiasing.py +++ b/tests/test_feature_debiasing.py @@ -13,7 +13,7 @@ def test_debiasing_count(test_pd_df, axis, exp): # modify the default test data to have three distinct scenarios test_pd_df.loc[1, "model"] = "model_b" df = IamDataFrame(test_pd_df) - df.compute_bias(method="count", name="bias", axis=axis) + df.compute.bias(method="count", name="bias", axis=axis) assert_array_equal(df["bias"].values, exp) @@ -22,4 +22,4 @@ def test_debiasing_unknown_method(test_df_year): """Check computing bias weights counting the number of scenarios by scenario name""" msg = "Unknown method foo for computing bias weights!" with pytest.raises(ValueError, match=msg): - test_df_year.compute_bias(method="foo", name="bias", axis="scenario") + test_df_year.compute.bias(method="foo", name="bias", axis="scenario")