-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
add a drop_conflicts strategy for merging attrs #4827
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
Changes from 23 commits
767a668
909c5cd
d35a213
7f9481c
1930d68
a14a4d9
edc8428
9344b93
1791111
2ec123f
fad94a0
86c7c5f
3531198
be5ad6a
5a6b551
af72603
dbc510a
344d822
6ed88f7
f43c0be
ac3c102
ea24b32
5dd73be
81c8271
4a4faa5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -258,27 +258,118 @@ def test_concat_join_kwarg(self): | |||||
) | ||||||
assert_identical(actual, expected) | ||||||
|
||||||
def test_concat_combine_attrs_kwarg(self): | ||||||
ds1 = Dataset({"a": ("x", [0])}, coords={"x": [0]}, attrs={"b": 42}) | ||||||
ds2 = Dataset({"a": ("x", [0])}, coords={"x": [1]}, attrs={"b": 42, "c": 43}) | ||||||
|
||||||
expected = {} | ||||||
expected["drop"] = Dataset({"a": ("x", [0, 0])}, {"x": [0, 1]}) | ||||||
expected["no_conflicts"] = Dataset( | ||||||
{"a": ("x", [0, 0])}, {"x": [0, 1]}, {"b": 42, "c": 43} | ||||||
) | ||||||
expected["override"] = Dataset({"a": ("x", [0, 0])}, {"x": [0, 1]}, {"b": 42}) | ||||||
|
||||||
with raises_regex(ValueError, "combine_attrs='identical'"): | ||||||
actual = concat([ds1, ds2], dim="x", combine_attrs="identical") | ||||||
with raises_regex(ValueError, "combine_attrs='no_conflicts'"): | ||||||
ds3 = ds2.copy(deep=True) | ||||||
ds3.attrs["b"] = 44 | ||||||
actual = concat([ds1, ds3], dim="x", combine_attrs="no_conflicts") | ||||||
@pytest.mark.parametrize( | ||||||
"combine_attrs, var1_attrs, var2_attrs, expected_attrs, expect_exception", | ||||||
[ | ||||||
( | ||||||
"no_conflicts", | ||||||
{"a": 1, "b": 2}, | ||||||
{"a": 1, "c": 3}, | ||||||
{"a": 1, "b": 2, "c": 3}, | ||||||
False, | ||||||
), | ||||||
("no_conflicts", {"a": 1, "b": 2}, {}, {"a": 1, "b": 2}, False), | ||||||
("no_conflicts", {}, {"a": 1, "c": 3}, {"a": 1, "c": 3}, False), | ||||||
( | ||||||
"no_conflicts", | ||||||
{"a": 1, "b": 2}, | ||||||
{"a": 4, "c": 3}, | ||||||
{"a": 1, "b": 2, "c": 3}, | ||||||
True, | ||||||
), | ||||||
("drop", {"a": 1, "b": 2}, {"a": 1, "c": 3}, {}, False), | ||||||
("identical", {"a": 1, "b": 2}, {"a": 1, "b": 2}, {"a": 1, "b": 2}, False), | ||||||
("identical", {"a": 1, "b": 2}, {"a": 1, "c": 3}, {"a": 1, "b": 2}, True), | ||||||
( | ||||||
"override", | ||||||
{"a": 1, "b": 2}, | ||||||
{"a": 4, "b": 5, "c": 3}, | ||||||
{"a": 1, "b": 2}, | ||||||
False, | ||||||
), | ||||||
( | ||||||
"drop_conflicts", | ||||||
{"a": 41, "b": 42, "c": 43}, | ||||||
{"b": 2, "c": 43, "d": 44}, | ||||||
{"a": 41, "c": 43, "d": 44}, | ||||||
False, | ||||||
), | ||||||
], | ||||||
) | ||||||
def test_concat_combine_attrs_kwarg( | ||||||
self, combine_attrs, var1_attrs, var2_attrs, expected_attrs, expect_exception | ||||||
): | ||||||
ds1 = Dataset({"a": ("x", [0])}, coords={"x": [0]}, attrs=var1_attrs) | ||||||
ds2 = Dataset({"a": ("x", [0])}, coords={"x": [1]}, attrs=var2_attrs) | ||||||
|
||||||
if expect_exception: | ||||||
with pytest.raises(ValueError, match=f"combine_attrs='{combine_attrs}'"): | ||||||
concat([ds1, ds2], dim="x", combine_attrs=combine_attrs) | ||||||
else: | ||||||
actual = concat([ds1, ds2], dim="x", combine_attrs=combine_attrs) | ||||||
expected = Dataset( | ||||||
{"a": ("x", [0, 0])}, {"x": [0, 1]}, attrs=expected_attrs | ||||||
) | ||||||
|
||||||
for combine_attrs in expected: | ||||||
assert_identical(actual, expected) | ||||||
|
||||||
@pytest.mark.skip(reason="not implemented, yet (see #4827)") | ||||||
@pytest.mark.parametrize( | ||||||
"combine_attrs, attrs1, attrs2, expected_attrs, expect_exception", | ||||||
[ | ||||||
( | ||||||
"no_conflicts", | ||||||
{"a": 1, "b": 2}, | ||||||
{"a": 1, "c": 3}, | ||||||
{"a": 1, "b": 2, "c": 3}, | ||||||
False, | ||||||
), | ||||||
("no_conflicts", {"a": 1, "b": 2}, {}, {"a": 1, "b": 2}, False), | ||||||
("no_conflicts", {}, {"a": 1, "c": 3}, {"a": 1, "c": 3}, False), | ||||||
( | ||||||
"no_conflicts", | ||||||
{"a": 1, "b": 2}, | ||||||
{"a": 4, "c": 3}, | ||||||
{"a": 1, "b": 2, "c": 3}, | ||||||
True, | ||||||
), | ||||||
("drop", {"a": 1, "b": 2}, {"a": 1, "c": 3}, {}, False), | ||||||
("identical", {"a": 1, "b": 2}, {"a": 1, "b": 2}, {"a": 1, "b": 2}, False), | ||||||
("identical", {"a": 1, "b": 2}, {"a": 1, "c": 3}, {"a": 1, "b": 2}, True), | ||||||
( | ||||||
"override", | ||||||
{"a": 1, "b": 2}, | ||||||
{"a": 4, "b": 5, "c": 3}, | ||||||
{"a": 1, "b": 2}, | ||||||
False, | ||||||
), | ||||||
( | ||||||
"drop_conflicts", | ||||||
{"a": 41, "b": 42, "c": 43}, | ||||||
{"b": 2, "c": 43, "d": 44}, | ||||||
{"a": 41, "c": 43, "d": 44}, | ||||||
False, | ||||||
), | ||||||
], | ||||||
) | ||||||
def test_concat_combine_attrs_kwarg_variables( | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
or There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. thanks, I forgot to check the coords. The purpose of these tests is to check whether |
||||||
self, combine_attrs, attrs1, attrs2, expected_attrs, expect_exception | ||||||
): | ||||||
"""check that combine_attrs is used on data variables and coords""" | ||||||
ds1 = Dataset({"a": ("x", [0], attrs1)}, coords={"x": ("x", [0], attrs1)}) | ||||||
ds2 = Dataset({"a": ("x", [0], attrs2)}, coords={"x": ("x", [1], attrs2)}) | ||||||
|
||||||
if expect_exception: | ||||||
with pytest.raises(ValueError, match=f"combine_attrs='{combine_attrs}'"): | ||||||
concat([ds1, ds2], dim="x", combine_attrs=combine_attrs) | ||||||
else: | ||||||
actual = concat([ds1, ds2], dim="x", combine_attrs=combine_attrs) | ||||||
assert_identical(actual, expected[combine_attrs]) | ||||||
expected = Dataset( | ||||||
{"a": ("x", [0, 0], expected_attrs)}, | ||||||
{"x": ("x", [0, 1], expected_attrs)}, | ||||||
) | ||||||
|
||||||
assert_identical(actual, expected) | ||||||
|
||||||
def test_concat_promote_shape(self): | ||||||
# mixed dims within variables | ||||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -92,6 +92,20 @@ def test_merge_arrays_attrs_default(self): | |
{"a": 1, "b": 2}, | ||
False, | ||
), | ||
( | ||
"drop_conflicts", | ||
{"a": 1, "b": 2, "c": 3}, | ||
{"b": 1, "c": 3, "d": 4}, | ||
{"a": 1, "c": 3, "d": 4}, | ||
False, | ||
), | ||
( | ||
"drop_conflicts", | ||
{"a": 1, "b": np.array([2]), "c": np.array([3])}, | ||
{"b": 1, "c": np.array([3]), "d": 4}, | ||
{"a": 1, "c": np.array([3]), "d": 4}, | ||
False, | ||
), | ||
], | ||
) | ||
def test_merge_arrays_attrs( | ||
|
@@ -109,13 +123,84 @@ def test_merge_arrays_attrs( | |
expected.attrs = expected_attrs | ||
assert_identical(actual, expected) | ||
|
||
@pytest.mark.skip(reason="not implemented, yet (see #4827)") | ||
@pytest.mark.parametrize( | ||
"combine_attrs, attrs1, attrs2, expected_attrs, expect_exception", | ||
[ | ||
( | ||
"no_conflicts", | ||
{"a": 1, "b": 2}, | ||
{"a": 1, "c": 3}, | ||
{"a": 1, "b": 2, "c": 3}, | ||
False, | ||
), | ||
("no_conflicts", {"a": 1, "b": 2}, {}, {"a": 1, "b": 2}, False), | ||
("no_conflicts", {}, {"a": 1, "c": 3}, {"a": 1, "c": 3}, False), | ||
( | ||
"no_conflicts", | ||
{"a": 1, "b": 2}, | ||
{"a": 4, "c": 3}, | ||
{"a": 1, "b": 2, "c": 3}, | ||
True, | ||
), | ||
("drop", {"a": 1, "b": 2}, {"a": 1, "c": 3}, {}, False), | ||
("identical", {"a": 1, "b": 2}, {"a": 1, "b": 2}, {"a": 1, "b": 2}, False), | ||
("identical", {"a": 1, "b": 2}, {"a": 1, "c": 3}, {"a": 1, "b": 2}, True), | ||
( | ||
"override", | ||
{"a": 1, "b": 2}, | ||
{"a": 4, "b": 5, "c": 3}, | ||
{"a": 1, "b": 2}, | ||
False, | ||
), | ||
( | ||
"drop_conflicts", | ||
{"a": 1, "b": 2, "c": 3}, | ||
{"b": 1, "c": 3, "d": 4}, | ||
{"a": 1, "c": 3, "d": 4}, | ||
False, | ||
), | ||
], | ||
) | ||
def test_merge_arrays_attrs_variables( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. dito |
||
self, combine_attrs, attrs1, attrs2, expected_attrs, expect_exception | ||
): | ||
"""check that combine_attrs is used on data variables and coords""" | ||
data = create_test_data() | ||
data1 = data.copy() | ||
data1.var1.attrs = attrs1 | ||
data1.dim1.attrs = attrs1 | ||
data2 = data.copy() | ||
data2.var1.attrs = attrs2 | ||
data2.dim1.attrs = attrs2 | ||
|
||
if expect_exception: | ||
with raises_regex(MergeError, "combine_attrs"): | ||
actual = xr.merge([data1, data2], combine_attrs=combine_attrs) | ||
else: | ||
actual = xr.merge([data1, data2], combine_attrs=combine_attrs) | ||
expected = data.copy() | ||
expected.var1.attrs = expected_attrs | ||
expected.dim1.attrs = expected_attrs | ||
|
||
assert_identical(actual, expected) | ||
|
||
def test_merge_attrs_override_copy(self): | ||
ds1 = xr.Dataset(attrs={"x": 0}) | ||
ds2 = xr.Dataset(attrs={"x": 1}) | ||
ds3 = xr.merge([ds1, ds2], combine_attrs="override") | ||
ds3.attrs["x"] = 2 | ||
assert ds1.x == 0 | ||
|
||
def test_merge_attrs_drop_conflicts(self): | ||
ds1 = xr.Dataset(attrs={"a": 0, "b": 0, "c": 0}) | ||
ds2 = xr.Dataset(attrs={"b": 0, "c": 1, "d": 0}) | ||
ds3 = xr.Dataset(attrs={"a": 0, "b": 1, "c": 0, "e": 0}) | ||
|
||
actual = xr.merge([ds1, ds2, ds3], combine_attrs="drop_conflicts") | ||
expected = xr.Dataset(attrs={"a": 0, "d": 0, "e": 0}) | ||
assert_identical(actual, expected) | ||
|
||
def test_merge_dicts_simple(self): | ||
actual = xr.merge([{"foo": 0}, {"bar": "one"}, {"baz": 3.5}]) | ||
expected = xr.Dataset({"foo": 0, "bar": "one", "baz": 3.5}) | ||
|
Uh oh!
There was an error while loading. Please reload this page.