Skip to content
This repository was archived by the owner on Oct 24, 2024. It is now read-only.

Commit b8511f1

Browse files
authored
Add filter method (#185)
* implement filter * test filter * whatsnew * add filter to API docs
1 parent f68dd3d commit b8511f1

File tree

4 files changed

+50
-0
lines changed

4 files changed

+50
-0
lines changed

datatree/datatree.py

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1102,6 +1102,28 @@ def identical(self, other: DataTree, from_root=True) -> bool:
11021102
for node, other_node in zip(self.subtree, other.subtree)
11031103
)
11041104

1105+
def filter(self: DataTree, filterfunc: Callable[[DataTree], bool]) -> DataTree:
1106+
"""
1107+
Filter nodes according to a specified condition.
1108+
1109+
Returns a new tree containing only the nodes in the original tree for which `fitlerfunc(node)` is True.
1110+
Will also contain empty nodes at intermediate positions if required to support leaves.
1111+
1112+
Parameters
1113+
----------
1114+
filterfunc: function
1115+
A function which accepts only one DataTree - the node on which filterfunc will be called.
1116+
1117+
See Also
1118+
--------
1119+
pipe
1120+
map_over_subtree
1121+
"""
1122+
filtered_nodes = {
1123+
node.path: node.ds for node in self.subtree if filterfunc(node)
1124+
}
1125+
return DataTree.from_dict(filtered_nodes, name=self.root.name)
1126+
11051127
def map_over_subtree(
11061128
self,
11071129
func: Callable,

datatree/tests/test_datatree.py

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -596,3 +596,28 @@ def f(x, tree, y):
596596
actual = dt.pipe((f, "tree"), **attrs)
597597

598598
assert actual is dt and actual.attrs == attrs
599+
600+
601+
class TestSubset:
602+
def test_filter(self):
603+
simpsons = DataTree.from_dict(
604+
d={
605+
"/": xr.Dataset({"age": 83}),
606+
"/Herbert": xr.Dataset({"age": 40}),
607+
"/Homer": xr.Dataset({"age": 39}),
608+
"/Homer/Bart": xr.Dataset({"age": 10}),
609+
"/Homer/Lisa": xr.Dataset({"age": 8}),
610+
"/Homer/Maggie": xr.Dataset({"age": 1}),
611+
},
612+
name="Abe",
613+
)
614+
expected = DataTree.from_dict(
615+
d={
616+
"/": xr.Dataset({"age": 83}),
617+
"/Herbert": xr.Dataset({"age": 40}),
618+
"/Homer": xr.Dataset({"age": 39}),
619+
},
620+
name="Abe",
621+
)
622+
elders = simpsons.filter(lambda node: node["age"] > 18)
623+
dtt.assert_identical(elders, expected)

docs/source/api.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ For manipulating, traversing, navigating, or mapping over the tree structure.
9999
DataTree.find_common_ancestor
100100
map_over_subtree
101101
DataTree.pipe
102+
DataTree.filter
102103

103104
DataTree Contents
104105
-----------------

docs/source/whats-new.rst

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ New Features
3131
By `Tom Nicholas <https://github.com/TomNicholas>`_.
3232
- Added a :py:meth:`DataTree.leaves` property (:pull:`177`).
3333
By `Tom Nicholas <https://github.com/TomNicholas>`_.
34+
- Added a :py:meth:`DataTree.filter` method (:pull:`184`).
35+
By `Tom Nicholas <https://github.com/TomNicholas>`_.
3436

3537
Breaking changes
3638
~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)