Skip to content

Commit def1121

Browse files
committed
add support for isolated vertices when creating graph from numpy array
1 parent 615b851 commit def1121

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

python/cugraph/cugraph/structure/convert_matrix.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -434,7 +434,7 @@ def to_pandas_adjacency(G):
434434
return pdf
435435

436436

437-
def from_numpy_array(A, create_using=Graph):
437+
def from_numpy_array(A, create_using=Graph, vertices=None):
438438
"""
439439
Initializes the graph from numpy array containing adjacency matrix.
440440
@@ -446,6 +446,14 @@ def from_numpy_array(A, create_using=Graph):
446446
create_using: cugraph.Graph (instance or class), optional (default=Graph)
447447
Specify the type of Graph to create. Can pass in an instance to create
448448
a Graph instance with specified 'directed' attribute.
449+
450+
vertices : cudf.Series or List, optional (default=None)
451+
A cudf.Series or list containing all vertices of the graph. This is
452+
optional, but must be used if the graph contains isolated vertices
453+
which cannot be represented in the source and destination arrays.
454+
If specified, this array must contain every vertex identifier,
455+
including vertex identifiers that are already included in the
456+
source and destination arrays.
449457
"""
450458
if create_using is None:
451459
G = Graph()
@@ -461,7 +469,7 @@ def from_numpy_array(A, create_using=Graph):
461469
f"{type(create_using)}"
462470
)
463471

464-
G.from_numpy_array(A)
472+
G.from_numpy_array(A, vertices=vertices)
465473
return G
466474

467475

python/cugraph/cugraph/structure/graph_classes.py

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ def from_pandas_adjacency(self, pdf):
489489
columns = pdf.columns
490490
self.from_numpy_array(np_array, columns)
491491

492-
def from_numpy_array(self, np_array, nodes=None):
492+
def from_numpy_array(self, np_array, nodes=None, vertices=None):
493493
"""
494494
Initializes the graph from numpy array containing adjacency matrix.
495495
@@ -500,6 +500,14 @@ def from_numpy_array(self, np_array, nodes=None):
500500
501501
nodes: array-like or None, optional (default=None)
502502
A list of column names, acting as labels for nodes
503+
504+
vertices : cudf.Series or List, optional (default=None)
505+
A cudf.Series or list containing all vertices of the graph. This is
506+
optional, but must be used if the graph contains isolated vertices
507+
which cannot be represented in the source and destination arrays.
508+
If specified, this array must contain every vertex identifier,
509+
including vertex identifiers that are already included in the
510+
source and destination arrays.
503511
"""
504512
np_array = np.asarray(np_array)
505513
if len(np_array.shape) != 2:
@@ -515,7 +523,7 @@ def from_numpy_array(self, np_array, nodes=None):
515523
df["src"] = src
516524
df["dst"] = dst
517525
df["weight"] = weight
518-
self.from_cudf_edgelist(df, "src", "dst", edge_attr="weight")
526+
self.from_cudf_edgelist(df, "src", "dst", edge_attr="weight", vertices=vertices)
519527

520528
def from_numpy_matrix(self, np_matrix):
521529
"""

python/cugraph/cugraph/tests/structure/test_graph.py

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import pandas as pd
1919
import scipy
2020
import networkx as nx
21+
import numpy as np
2122

2223
import cupy
2324
import cudf
@@ -646,6 +647,35 @@ def test_number_of_edges():
646647
assert G_directed.number_of_edges() == G_undirected.number_of_edges()
647648

648649

650+
@pytest.mark.sg
651+
def test_vertex_list():
652+
A = np.array([[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
653+
[0., 0., 0., 0., 0., 1., 0., 0., 1., 0.],
654+
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
655+
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
656+
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
657+
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
658+
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.],
659+
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
660+
[0., 0., 0., 0., 0., 0., 0., 1., 0., 0.],
661+
[0., 0., 0., 0., 0., 0., 0., 0., 0., 0.]])
662+
663+
G = nx.from_numpy_array(A)
664+
cG = cugraph.from_numpy_array(nx.to_numpy_array(G))
665+
666+
assert len(G.nodes()) == len(cG.nodes())
667+
668+
nx_nodes = cudf.Series([n for n in G.nodes()])
669+
cG_nodes = cG.nodes().sort_values(ignore_index=True)
670+
671+
assert_series_equal(
672+
nx_nodes,
673+
cG_nodes,
674+
check_names=False,
675+
check_dtype=False,
676+
)
677+
678+
649679
# Test
650680
@pytest.mark.sg
651681
@pytest.mark.parametrize("graph_file", utils.DATASETS_SMALL)

0 commit comments

Comments
 (0)