Skip to content

Commit

Permalink
Implement set operations for NodeView and EdgeView (#208)
Browse files Browse the repository at this point in the history
* Feat: now NodeViews and EdgeViews support set operations. Fixes #206.
* update tutorial to include set operations
  • Loading branch information
leotrs authored Nov 2, 2022
1 parent 93320f5 commit 743939f
Show file tree
Hide file tree
Showing 3 changed files with 138 additions and 50 deletions.
20 changes: 20 additions & 0 deletions tests/classes/test_reportviews.py
Original file line number Diff line number Diff line change
Expand Up @@ -242,3 +242,23 @@ def test_bool(edgelist1):
assert bool(H.edges) is False
H = xgi.Hypergraph(edgelist1)
assert bool(H.edges) is True


def test_set_operations(hyperwithattrs):
H = hyperwithattrs

nodes1 = H.nodes.filterby_attr("color", "blue")
nodes2 = H.nodes.filterby("degree", 2, "geq")
assert set(nodes2 - nodes1) == {3, 4}
assert set(nodes1 - nodes2) == set()
assert set(nodes1 & nodes2) == {2, 5}
assert set(nodes1 | nodes2) == {2, 3, 4, 5}
assert set(nodes1 ^ nodes2) == {3, 4}

edges1 = H.edges
edges2 = H.edges.filterby("size", 3, "leq")
assert set(edges2 - edges1) == set()
assert set(edges1 - edges2) == {1}
assert set(edges1 & edges2) == {0, 2}
assert set(edges1 | edges2) == {0, 1, 2}
assert set(edges1 ^ edges2) == {1}
159 changes: 109 additions & 50 deletions tutorials/Tutorial 6 - Statistics.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,78 @@
"H.nodes.filterby(\"degree\", H.nodes.degree.max())"
]
},
{
"cell_type": "markdown",
"id": "cc5df033",
"metadata": {},
"source": [
"## Set operations"
]
},
{
"cell_type": "markdown",
"id": "11548f49",
"metadata": {},
"source": [
"Another way of chaining multiple results of `filterby*` methods is by using set operations. Indeed, chaining two filters is the same as intersecting the results of two separate calls:"
]
},
{
"cell_type": "code",
"execution_count": 26,
"id": "970da532",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"[2, 5]\n",
"[2, 5]\n"
]
}
],
"source": [
"print(H.nodes.filterby(\"degree\", 2).filterby_attr(\"color\", \"blue\"))\n",
"print(H.nodes.filterby(\"degree\", 2) & H.nodes.filterby_attr(\"color\", \"blue\"))"
]
},
{
"cell_type": "markdown",
"id": "dc0ff694",
"metadata": {},
"source": [
"Other set operations are also supported."
]
},
{
"cell_type": "code",
"execution_count": 27,
"id": "65c22a67",
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"nodes1 - nodes2 = [4]\n",
"nodes2 - nodes1 = []\n",
"nodes1 & nodes2 = [2, 5]\n",
"nodes1 | nodes2 = [2, 4, 5]\n",
"nodes1 ^ nodes2 = [4]\n"
]
}
],
"source": [
"nodes1 = H.nodes.filterby(\"degree\", 2)\n",
"nodes2 = H.nodes.filterby_attr(\"color\", \"blue\")\n",
"print(f\"nodes1 - nodes2 = {nodes1 - nodes2}\")\n",
"print(f\"nodes2 - nodes1 = {nodes2 - nodes1}\")\n",
"print(f\"nodes1 & nodes2 = {nodes1 & nodes2}\")\n",
"print(f\"nodes1 | nodes2 = {nodes1 | nodes2}\")\n",
"print(f\"nodes1 ^ nodes2 = {nodes1 ^ nodes2}\")"
]
},
{
"cell_type": "markdown",
"id": "697055d8",
Expand All @@ -760,7 +832,7 @@
},
{
"cell_type": "code",
"execution_count": 26,
"execution_count": 28,
"id": "09aeadef",
"metadata": {},
"outputs": [
Expand All @@ -770,7 +842,7 @@
"MultiNodeStat(degree, clustering)"
]
},
"execution_count": 26,
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -789,7 +861,7 @@
},
{
"cell_type": "code",
"execution_count": 27,
"execution_count": 29,
"id": "31619b17",
"metadata": {
"scrolled": true
Expand All @@ -805,7 +877,7 @@
" 5: {'degree': 2, 'clustering': 3.0}}"
]
},
"execution_count": 27,
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -824,7 +896,7 @@
},
{
"cell_type": "code",
"execution_count": 28,
"execution_count": 30,
"id": "c29d8461",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -903,7 +975,7 @@
},
{
"cell_type": "code",
"execution_count": 29,
"execution_count": 31,
"id": "250d2808",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -971,7 +1043,7 @@
"5 2 3.000000"
]
},
"execution_count": 29,
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -991,7 +1063,7 @@
},
{
"cell_type": "code",
"execution_count": 30,
"execution_count": 32,
"id": "3c47eac0",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -1048,7 +1120,7 @@
"3 1.333333"
]
},
"execution_count": 30,
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1067,7 +1139,7 @@
},
{
"cell_type": "code",
"execution_count": 31,
"execution_count": 33,
"id": "d28315b8",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -1098,7 +1170,7 @@
},
{
"cell_type": "code",
"execution_count": 32,
"execution_count": 34,
"id": "a6c92003",
"metadata": {
"scrolled": true
Expand Down Expand Up @@ -1174,7 +1246,7 @@
"5 2 1 blue"
]
},
"execution_count": 32,
"execution_count": 34,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1196,12 +1268,12 @@
"id": "29d4aa9f",
"metadata": {},
"source": [
"Every feature showcased above (lazy evaluation, type conversion, filtering, and multi objects) is supported for edge-quantity or edge-attribute mappings, via `EdgeStat` objects."
"Every feature showcased above (lazy evaluation, type conversion, filtering, set operations, and multi objects) is supported for edge-quantity or edge-attribute mappings, via `EdgeStat` objects."
]
},
{
"cell_type": "code",
"execution_count": 33,
"execution_count": 35,
"id": "3a43de55",
"metadata": {},
"outputs": [
Expand All @@ -1211,7 +1283,7 @@
"EdgeStat('order')"
]
},
"execution_count": 33,
"execution_count": 35,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1222,7 +1294,7 @@
},
{
"cell_type": "code",
"execution_count": 34,
"execution_count": 36,
"id": "9e708cda",
"metadata": {},
"outputs": [
Expand All @@ -1232,7 +1304,7 @@
"{0: 2, 1: 3, 2: 2}"
]
},
"execution_count": 34,
"execution_count": 36,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1243,7 +1315,7 @@
},
{
"cell_type": "code",
"execution_count": 35,
"execution_count": 37,
"id": "29154c7e",
"metadata": {},
"outputs": [
Expand All @@ -1253,7 +1325,7 @@
"EdgeView((1,))"
]
},
"execution_count": 35,
"execution_count": 37,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1264,7 +1336,7 @@
},
{
"cell_type": "code",
"execution_count": 36,
"execution_count": 38,
"id": "6b319bfc",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -1320,7 +1392,7 @@
"2 2 3"
]
},
"execution_count": 36,
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
Expand Down Expand Up @@ -1349,7 +1421,7 @@
},
{
"cell_type": "code",
"execution_count": 37,
"execution_count": 39,
"id": "fec60de5",
"metadata": {},
"outputs": [],
Expand All @@ -1360,9 +1432,17 @@
" return {n: 10 * net.degree(n) for n in bunch}"
]
},
{
"cell_type": "markdown",
"id": "b0be4a0d",
"metadata": {},
"source": [
"Now `user_degree` is a valid stat that can be computed on any hypergraph:"
]
},
{
"cell_type": "code",
"execution_count": 38,
"execution_count": 40,
"id": "7409ae74",
"metadata": {},
"outputs": [
Expand All @@ -1372,7 +1452,7 @@
"{1: 10, 2: 20, 3: 30, 4: 20, 5: 20}"
]
},
"execution_count": 38,
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1386,12 +1466,12 @@
"id": "65f4b7bf",
"metadata": {},
"source": [
"Now every single feature showcased above is available for use with `user_degree`, including filtering nodes and multi stats objects."
"Every single feature showcased above is available for use with `user_degree`, including filtering nodes and multi stats objects."
]
},
{
"cell_type": "code",
"execution_count": 39,
"execution_count": 41,
"id": "314751dc",
"metadata": {},
"outputs": [
Expand All @@ -1401,7 +1481,7 @@
"NodeView((2, 4, 5))"
]
},
"execution_count": 39,
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1412,7 +1492,7 @@
},
{
"cell_type": "code",
"execution_count": 40,
"execution_count": 42,
"id": "7ae354dd",
"metadata": {},
"outputs": [
Expand Down Expand Up @@ -1480,7 +1560,7 @@
"5 2 20"
]
},
"execution_count": 40,
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
Expand All @@ -1505,27 +1585,6 @@
"User-defined edge statistics can similarly be defined using the `@xgi.edgestat` decorator."
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5ee7467f",
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"4"
]
},
"execution_count": 1,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"2 + 2"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand Down
Loading

0 comments on commit 743939f

Please sign in to comment.