From 7435809b9fbaf1c319fefe0c0478062d9024d411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florentin=20D=C3=B6rre?= Date: Wed, 28 May 2025 16:00:16 +0200 Subject: [PATCH 1/4] Stream relationship properties back from gds --- python-wrapper/src/neo4j_viz/gds.py | 20 +++++++++++++++++--- python-wrapper/tests/test_gds.py | 14 ++++++++++---- 2 files changed, 27 insertions(+), 7 deletions(-) diff --git a/python-wrapper/src/neo4j_viz/gds.py b/python-wrapper/src/neo4j_viz/gds.py index 911d648f..2c68ce9b 100644 --- a/python-wrapper/src/neo4j_viz/gds.py +++ b/python-wrapper/src/neo4j_viz/gds.py @@ -22,6 +22,20 @@ def _node_dfs( def _rel_df(gds: GraphDataScience, G: Graph) -> pd.DataFrame: + relationship_properties = G.relationship_properties() + + if len(relationship_properties) > 0: + if isinstance(relationship_properties, pd.Series): + relationship_properties_per_type = relationship_properties.tolist() + property_set: set[str] = set() + for props in relationship_properties_per_type: + if props: + property_set.update(props) + + return gds.graph.relationshipProperties.stream( + G, relationship_properties=list(property_set), separate_property_columns=True + ) + return gds.graph.relationships.stream(G) @@ -89,10 +103,10 @@ def from_gds( df.rename(columns={"labels": "__labels"}, inplace=True) df["labels"] = lbl - node_lbls_df = pd.concat([df[["id", "labels"]] for df in node_dfs.values()], ignore_index=True, axis=0) - node_lbls_df = node_lbls_df.groupby("id").agg({"labels": list}) + node_labels_df = pd.concat([df[["id", "labels"]] for df in node_dfs.values()], ignore_index=True, axis=0) + node_labels_df = node_labels_df.groupby("id").agg({"labels": list}) - node_df = node_props_df.merge(node_lbls_df, on="id") + node_df = node_props_df.merge(node_labels_df, on="id") rel_df = _rel_df(gds, G) rel_df.rename(columns={"sourceNodeId": "source", "targetNodeId": "target"}, inplace=True) diff --git a/python-wrapper/tests/test_gds.py b/python-wrapper/tests/test_gds.py index a5243459..62d1345d 100644 --- a/python-wrapper/tests/test_gds.py +++ b/python-wrapper/tests/test_gds.py @@ -24,6 +24,8 @@ def test_from_gds_integration(gds: Any) -> None: { "sourceNodeId": [0, 1, 2], "targetNodeId": [1, 2, 0], + "cost": [1.0, 2.0, 3.0], + "weight": [0.5, 1.5, 2.5], "relationshipType": ["REL", "REL2", "REL"], } ) @@ -46,12 +48,16 @@ def test_from_gds_integration(gds: Any) -> None: assert len(VG.relationships) == 3 vg_rels = sorted( - [(e.source, e.target, e.properties["relationshipType"]) for e in VG.relationships], key=lambda x: x[0] + [ + (e.source, e.target, e.properties["relationshipType"], e.properties["cost"], e.properties["weight"]) + for e in VG.relationships + ], + key=lambda x: x[0], ) assert vg_rels == [ - (0, 1, "REL"), - (1, 2, "REL2"), - (2, 0, "REL"), + (0, 1, "REL", 1.0, 0.5), + (1, 2, "REL2", 2.0, 1.0), + (2, 0, "REL", 3.0, 1.5), ] From 20f360f2a7f477f324f0a0b0c780745797db7476 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florentin=20D=C3=B6rre?= Date: Wed, 28 May 2025 16:08:48 +0200 Subject: [PATCH 2/4] Add similarity relationships to gds example --- examples/gds-example.ipynb | 167 +++++++++++++++++++------------------ 1 file changed, 88 insertions(+), 79 deletions(-) diff --git a/examples/gds-example.ipynb b/examples/gds-example.ipynb index f9a36b60..0afaa729 100644 --- a/examples/gds-example.ipynb +++ b/examples/gds-example.ipynb @@ -62,6 +62,7 @@ "outputs": [], "source": [ "# Run some algorithms to use later for visualization\n", + "gds.nodeSimilarity.mutate(G, mutateRelationshipType=\"SIMILAR\", mutateProperty=\"similarity\")\n", "gds.pageRank.mutate(G, mutateProperty=\"pagerank\")\n", "gds.louvain.mutate(G, mutateProperty=\"componentId\")" ] @@ -92,6 +93,15 @@ "G_sample.node_properties()" ] }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "G_sample.relationship_properties()" + ] + }, { "cell_type": "markdown", "metadata": {}, @@ -107,7 +117,6 @@ "source": [ "from neo4j_viz.gds import from_gds\n", "\n", - "# TODO inform about automatic size scaling\n", "VG = from_gds(\n", " gds,\n", " G_sample,\n", @@ -118,7 +127,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": { "tags": [ "preserve-output" @@ -185,27 +194,27 @@ "}\n", "\n", " \n", - "
\n", + "
\n", "
\n", - " \n", - " \n", - " \n", "
\n", - "
\n", + "
\n", "
\n", "\n", "