Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable casting to IamDataFrame multiple times #396

Merged
1 change: 1 addition & 0 deletions RELEASE_NOTES.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Next Release

- [#396](https://github.com/IAMconsortium/pyam/pull/396) Enable casting to `IamDataFrame` multiple times
- [#394](https://github.com/IAMconsortium/pyam/pull/394) Switch CI to Github Actions.
- [#393](https://github.com/IAMconsortium/pyam/pull/393) Import ABC from collections.abc for Python 3.10 compatibility.
- [#380](https://github.com/IAMconsortium/pyam/pull/380) Add compatibility with latest matplotlib and py3.8
Expand Down
8 changes: 8 additions & 0 deletions pyam/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,14 @@ class IamDataFrame(object):
"""
def __init__(self, data, **kwargs):
"""Initialize an instance of an IamDataFrame"""
if isinstance(data, IamDataFrame) and not kwargs:
for attr, value in data.__dict__.items():
setattr(self, attr, value)
else:
self._init(data, **kwargs)

def _init(self, data, **kwargs):
"""Process data and set attributes for new instance"""
# import data from pd.DataFrame or read from source
if isinstance(data, pd.DataFrame) or isinstance(data, pd.Series):
_data = format_data(data.copy(), **kwargs)
Expand Down
13 changes: 13 additions & 0 deletions tests/test_core.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,19 @@ def test_init_df_with_index(test_pd_df):
pd.testing.assert_frame_equal(df.timeseries().reset_index(), test_pd_df)


def test_init_from_iamdf(test_df_year):
znicholls marked this conversation as resolved.
Show resolved Hide resolved
# casting an IamDataFrame instance again works
df = IamDataFrame(test_df_year)

# inplace-operations on the new object have effects on the original object
df.rename(scenario={'scen_a': 'scen_foo'}, inplace=True)
assert all(test_df_year.scenarios().values == ['scen_b', 'scen_foo'])

# overwrites on the new object do not have effects on the original object
df = df.rename(scenario={'scen_foo': 'scen_bar'})
assert all(df.scenarios().values == ['scen_b', 'scen_bar'])
assert all(test_df_year.scenarios().values == ['scen_b', 'scen_foo'])

def test_init_df_with_float_cols_raises(test_pd_df):
_test_df = test_pd_df.rename(columns={2005: 2005.5, 2010: 2010.})
pytest.raises(ValueError, IamDataFrame, data=_test_df)
Expand Down