From acda5321151096c768ca62e7cc946ebbd2de7d38 Mon Sep 17 00:00:00 2001 From: Daniel Huppmann Date: Mon, 20 Jul 2026 09:51:33 +0200 Subject: [PATCH 1/3] Add an IamDataFrame.series attribute to get internal `_data` --- pyam/core.py | 5 +++++ tests/test_core.py | 8 ++++++++ 2 files changed, 13 insertions(+) diff --git a/pyam/core.py b/pyam/core.py index b65714104..7ba2ad36f 100755 --- a/pyam/core.py +++ b/pyam/core.py @@ -433,6 +433,11 @@ def data(self): return pd.DataFrame([], columns=self.dimensions + ["value"]) return self._data.reset_index() + @property + def series(self): + """Return the timeseries data as an indexed :class:`pandas.Series`""" + return self._data + def sort_data(self, inplace=False): """Sort timeseries data by index and coordinates diff --git a/tests/test_core.py b/tests/test_core.py index 9dbf80f5f..372c0583e 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -332,6 +332,14 @@ def test_print_empty(test_df_year): assert obs == exp +def test_pandas_types(test_df): + + series = test_df.series + data = test_df.data + + pdt.assert_frame_equal(series.reset_index(), data) + + def test_as_pandas(test_df): # test that `as_pandas()` returns the right columns df = test_df.copy() From d51237b6c81f612d1b87f139052e6973141a0270 Mon Sep 17 00:00:00 2001 From: Daniel Huppmann Date: Mon, 20 Jul 2026 10:04:57 +0200 Subject: [PATCH 2/3] Add to release notes --- RELEASE_NOTES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/RELEASE_NOTES.md b/RELEASE_NOTES.md index fc8aba068..764d06d3a 100644 --- a/RELEASE_NOTES.md +++ b/RELEASE_NOTES.md @@ -1,3 +1,8 @@ +# Next release + +- [#989](https://github.com/IAMconsortium/pyam/pull/989) Add an `IamDataFrame.series` attribute to get timeseries data + as **pd.Series** + # Release v3.3.3 ## Highlights From 7c0f55cfbf6b266383e96add24bf1f074597e2c9 Mon Sep 17 00:00:00 2001 From: Daniel Huppmann Date: Wed, 22 Jul 2026 18:56:41 +0200 Subject: [PATCH 3/3] Yield a copy of the pd.Series --- pyam/core.py | 2 +- tests/test_core.py | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/pyam/core.py b/pyam/core.py index 7ba2ad36f..4c11b8132 100755 --- a/pyam/core.py +++ b/pyam/core.py @@ -436,7 +436,7 @@ def data(self): @property def series(self): """Return the timeseries data as an indexed :class:`pandas.Series`""" - return self._data + return self._data.copy() def sort_data(self, inplace=False): """Sort timeseries data by index and coordinates diff --git a/tests/test_core.py b/tests/test_core.py index 372c0583e..8c7aa6796 100644 --- a/tests/test_core.py +++ b/tests/test_core.py @@ -337,8 +337,13 @@ def test_pandas_types(test_df): series = test_df.series data = test_df.data + # assert that data and series yield the same result as different types pdt.assert_frame_equal(series.reset_index(), data) + # check that `series` yields a copy and changes to not affect the IamDataFrame + series.iloc[0] = -2 + pdt.assert_frame_equal(test_df.series.reset_index(), data) + def test_as_pandas(test_df): # test that `as_pandas()` returns the right columns