easygraph.utils.convert_to_matrix module#

easygraph.utils.convert_to_matrix.from_numpy_array(A, parallel_edges=False, create_using=None)[source]#

Returns a graph from a 2D NumPy array.

The 2D NumPy array is interpreted as an adjacency matrix for the graph.

Parameters:
  • A (a 2D numpy.ndarray) – An adjacency matrix representation of a graph

  • parallel_edges (Boolean) – If this is True, create_using is a multigraph, and A is an integer array, then entry (i, j) in the array is interpreted as the number of parallel edges joining vertices i and j in the graph. If it is False, then the entries in the array are interpreted as the weight of a single edge joining the vertices.

  • create_using (EasyGraph graph constructor, optional (default=eg.Graph)) – Graph type to create. If graph instance, then cleared before populated.

Notes

For directed graphs, explicitly mention create_using=eg.DiGraph, and entry i,j of A corresponds to an edge from i to j.

If create_using is easygraph.MultiGraph or easygraph.MultiDiGraph, parallel_edges is True, and the entries of A are of type int, then this function returns a multigraph (of the same type as create_using) with parallel edges.

If create_using indicates an undirected multigraph, then only the edges indicated by the upper triangle of the array A will be added to the graph.

If the NumPy array has a single data type for each array entry it will be converted to an appropriate Python data type.

If the NumPy array has a user-specified compound data type the names of the data fields will be used as attribute keys in the resulting EasyGraph graph.

See also

to_numpy_array

Examples

Simple integer weights on edges:

>>> import numpy as np
>>> A = np.array([[1, 1], [2, 1]])
>>> G = eg.from_numpy_array(A)
>>> G.edges(data=True)
EdgeDataView([(0, 0, {'weight': 1}), (0, 1, {'weight': 2}), (1, 1, {'weight': 1})])

If create_using indicates a multigraph and the array has only integer entries and parallel_edges is False, then the entries will be treated as weights for edges joining the nodes (without creating parallel edges):

>>> A = np.array([[1, 1], [1, 2]])
>>> G = eg.from_numpy_array(A, create_using=eg.MultiGraph)
>>> G[1][1]
AtlasView({0: {'weight': 2}})

If create_using indicates a multigraph and the array has only integer entries and parallel_edges is True, then the entries will be treated as the number of parallel edges joining those two vertices:

>>> A = np.array([[1, 1], [1, 2]])
>>> temp = eg.MultiGraph()
>>> G = eg.from_numpy_array(A, parallel_edges=True, create_using=temp)
>>> G[1][1]
AtlasView({0: {'weight': 1}, 1: {'weight': 1}})

User defined compound data type on edges:

>>> dt = [("weight", float), ("cost", int)]
>>> A = np.array([[(1.0, 2)]], dtype=dt)
>>> G = eg.from_numpy_array(A)
>>> G.edges()
EdgeView([(0, 0)])
>>> G[0][0]["cost"]
2
>>> G[0][0]["weight"]
1.0
easygraph.utils.convert_to_matrix.from_pandas_adjacency(df, create_using=None)[source]#

Returns a graph from Pandas DataFrame.

The Pandas DataFrame is interpreted as an adjacency matrix for the graph.

Parameters:
  • df (Pandas DataFrame) – An adjacency matrix representation of a graph

  • create_using (EasyGraph graph constructor, optional (default=eg.Graph)) – Graph type to create. If graph instance, then cleared before populated.

Notes

For directed graphs, explicitly mention create_using=eg.DiGraph, and entry i,j of df corresponds to an edge from i to j.

If df has a single data type for each entry it will be converted to an appropriate Python data type.

If df has a user-specified compound data type the names of the data fields will be used as attribute keys in the resulting EasyGraph graph.

See also

to_pandas_adjacency

Examples

Simple integer weights on edges:

>>> import pandas as pd
>>> pd.options.display.max_columns = 20
>>> df = pd.DataFrame([[1, 1], [2, 1]])
>>> df
   0  1
0  1  1
1  2  1
>>> G = eg.from_pandas_adjacency(df)
>>> G.name = "Graph from pandas adjacency matrix"
easygraph.utils.convert_to_matrix.from_pandas_edgelist(df, source='source', target='target', edge_attr=None, create_using=None, edge_key=None)[source]#

Returns a graph from Pandas DataFrame containing an edge list.

The Pandas DataFrame should contain at least two columns of node names and zero or more columns of edge attributes. Each row will be processed as one edge instance.

Note: This function iterates over DataFrame.values, which is not guaranteed to retain the data type across columns in the row. This is only a problem if your row is entirely numeric and a mix of ints and floats. In that case, all values will be returned as floats. See the DataFrame.iterrows documentation for an example.

Parameters:
  • df (Pandas DataFrame) – An edge list representation of a graph

  • source (str or int) – A valid column name (string or integer) for the source nodes (for the directed case).

  • target (str or int) – A valid column name (string or integer) for the target nodes (for the directed case).

  • edge_attr (str or int, iterable, True, or None) – A valid column name (str or int) or iterable of column names that are used to retrieve items and add them to the graph as edge attributes. If True, all of the remaining columns will be added. If None, no edge attributes are added to the graph.

  • create_using (EasyGraph graph constructor, optional (default=eg.Graph)) – Graph type to create. If graph instance, then cleared before populated.

  • edge_key (str or None, optional (default=None)) – A valid column name for the edge keys (for a MultiGraph). The values in this column are used for the edge keys when adding edges if create_using is a multigraph.

See also

to_pandas_edgelist

Examples

Simple integer weights on edges:

>>> import pandas as pd
>>> pd.options.display.max_columns = 20
>>> import numpy as np
>>> rng = np.random.RandomState(seed=5)
>>> ints = rng.randint(1, 11, size=(3, 2))
>>> a = ["A", "B", "C"]
>>> b = ["D", "A", "E"]
>>> df = pd.DataFrame(ints, columns=["weight", "cost"])
>>> df[0] = a
>>> df["b"] = b
>>> df[["weight", "cost", 0, "b"]]
   weight  cost  0  b
0       4     7  A  D
1       7     1  B  A
2      10     9  C  E
>>> G = eg.from_pandas_edgelist(df, 0, "b", ["weight", "cost"])
>>> G["E"]["C"]["weight"]
10
>>> G["E"]["C"]["cost"]
9
>>> edges = pd.DataFrame(
...     {
...         "source": [0, 1, 2],
...         "target": [2, 2, 3],
...         "weight": [3, 4, 5],
...         "color": ["red", "blue", "blue"],
...     }
... )
>>> G = eg.from_pandas_edgelist(edges, edge_attr=True)
>>> G[0][2]["color"]
'red'

Build multigraph with custom keys:

>>> edges = pd.DataFrame(
...     {
...         "source": [0, 1, 2, 0],
...         "target": [2, 2, 3, 2],
...         "my_edge_key": ["A", "B", "C", "D"],
...         "weight": [3, 4, 5, 6],
...         "color": ["red", "blue", "blue", "blue"],
...     }
... )
>>> G = eg.from_pandas_edgelist(
...     edges,
...     edge_key="my_edge_key",
...     edge_attr=["weight", "color"],
...     create_using=eg.MultiGraph(),
... )
>>> G[0][2]
AtlasView({'A': {'weight': 3, 'color': 'red'}, 'D': {'weight': 6, 'color': 'blue'}})
easygraph.utils.convert_to_matrix.from_scipy_sparse_matrix(A, parallel_edges=False, create_using=None, edge_attribute='weight')[source]#

Creates a new graph from an adjacency matrix given as a SciPy sparse matrix.

Parameters:
  • A (scipy sparse matrix) – An adjacency matrix representation of a graph

  • parallel_edges (Boolean) – If this is True, create_using is a multigraph, and A is an integer matrix, then entry (i, j) in the matrix is interpreted as the number of parallel edges joining vertices i and j in the graph. If it is False, then the entries in the matrix are interpreted as the weight of a single edge joining the vertices.

  • create_using (EasyGraph graph constructor, optional (default=eg.Graph)) – Graph type to create. If graph instance, then cleared before populated.

  • edge_attribute (string) – Name of edge attribute to store matrix numeric value. The data will have the same type as the matrix entry (int, float, (real,imag)).

Notes

For directed graphs, explicitly mention create_using=eg.DiGraph, and entry i,j of A corresponds to an edge from i to j.

If create_using is easygraph.MultiGraph or easygraph.MultiDiGraph, parallel_edges is True, and the entries of A are of type int, then this function returns a multigraph (constructed from create_using) with parallel edges. In this case, edge_attribute will be ignored.

If create_using indicates an undirected multigraph, then only the edges indicated by the upper triangle of the matrix A will be added to the graph.

Examples

>>> import scipy as sp
>>> import scipy.sparse  # call as sp.sparse
>>> A = sp.sparse.eye(2, 2, 1)
>>> G = eg.from_scipy_sparse_matrix(A)

If create_using indicates a multigraph and the matrix has only integer entries and parallel_edges is Falnxse, then the entries will be treated as weights for edges joining the nodes (without creating parallel edges):

>>> A = sp.sparse.csr_matrix([[1, 1], [1, 2]])
>>> G = eg.from_scipy_sparse_matrix(A, create_using=eg.MultiGraph)
>>> G[1][1]
AtlasView({0: {'weight': 2}})

If create_using indicates a multigraph and the matrix has only integer entries and parallel_edges is True, then the entries will be treated as the number of parallel edges joining those two vertices:

>>> A = sp.sparse.csr_matrix([[1, 1], [1, 2]])
>>> G = eg.from_scipy_sparse_matrix(
...     A, parallel_edges=True, create_using=eg.MultiGraph
... )
>>> G[1][1]
AtlasView({0: {'weight': 1}, 1: {'weight': 1}})
easygraph.utils.convert_to_matrix.to_numpy_array(G, nodelist=None, dtype=None, order=None, multigraph_weight=<built-in function sum>, weight='weight', nonedge=0.0)[source]#

Returns the graph adjacency matrix as a NumPy array.

Parameters:
  • G (graph) – The EasyGraph graph used to construct the NumPy array.

  • nodelist (list, optional) – The rows and columns are ordered according to the nodes in nodelist. If nodelist is None, then the ordering is produced by G.nodes().

  • dtype (NumPy data type, optional) – A valid single NumPy data type used to initialize the array. This must be a simple type such as int or numpy.float64 and not a compound data type (see to_numpy_recarray) If None, then the NumPy default is used.

  • order ({'C', 'F'}, optional) – Whether to store multidimensional data in C- or Fortran-contiguous (row- or column-wise) order in memory. If None, then the NumPy default is used.

  • multigraph_weight ({sum, min, max}, optional) – An operator that determines how weights in multigraphs are handled. The default is to sum the weights of the multiple edges.

  • weight (string or None optional (default = 'weight')) – The edge attribute that holds the numerical value used for the edge weight. If an edge does not have that attribute, then the value 1 is used instead.

  • nonedge (float (default = 0.0)) – The array values corresponding to nonedges are typically set to zero. However, this could be undesirable if there are array values corresponding to actual edges that also have the value zero. If so, one might prefer nonedges to have some other value, such as nan.

Returns:

A – Graph adjacency matrix

Return type:

NumPy ndarray

See also

from_numpy_array

Notes

For directed graphs, entry i,j corresponds to an edge from i to j.

Entries in the adjacency matrix are assigned to the weight edge attribute. When an edge does not have a weight attribute, the value of the entry is set to the number 1. For multiple (parallel) edges, the values of the entries are determined by the multigraph_weight parameter. The default is to sum the weight attributes for each of the parallel edges.

When nodelist does not contain every node in G, the adjacency matrix is built from the subgraph of G that is induced by the nodes in nodelist.

The convention used for self-loop edges in graphs is to assign the diagonal array entry value to the weight attribute of the edge (or the number 1 if the edge has no weight attribute). If the alternate convention of doubling the edge weight is desired the resulting NumPy array can be modified as follows:

>>> import numpy as np
>>> G = eg.Graph([(1, 1)])
>>> A = eg.to_numpy_array(G)
>>> A
array([[1.]])
>>> A[np.diag_indices_from(A)] *= 2
>>> A
array([[2.]])

Examples

>>> G = eg.MultiDiGraph()
>>> G.add_edge(0, 1, weight=2)
0
>>> G.add_edge(1, 0)
0
>>> G.add_edge(2, 2, weight=3)
0
>>> G.add_edge(2, 2)
1
>>> eg.to_numpy_array(G, nodelist=[0, 1, 2])
array([[0., 2., 0.],
       [1., 0., 0.],
       [0., 0., 4.]])
easygraph.utils.convert_to_matrix.to_numpy_matrix(G, edge_sign=1.0, not_edge_sign=0.0)[source]#

Returns the graph adjacency matrix as a NumPy matrix.

Parameters:
  • edge_sign (float) – Sign for the position of matrix where there is an edge

  • not_edge_sign (float) – Sign for the position of matrix where there is no edge

easygraph.utils.convert_to_matrix.to_scipy_sparse_array(G, nodelist=None, dtype=None, weight='weight', format='csr')[source]#

Returns the graph adjacency matrix as a SciPy sparse array.

Parameters:
  • G (graph) – The EasyGraph graph used to construct the sparse matrix.

  • nodelist (list, optional) – The rows and columns are ordered according to the nodes in nodelist. If nodelist is None, then the ordering is produced by G.nodes().

  • dtype (NumPy data-type, optional) – A valid NumPy dtype used to initialize the array. If None, then the NumPy default is used.

  • weight (string or None optional (default='weight')) – The edge attribute that holds the numerical value used for the edge weight. If None then all edge weights are 1.

  • format (str in {'bsr', 'csr', 'csc', 'coo', 'lil', 'dia', 'dok'}) – The type of the matrix to be returned (default ‘csr’). For some algorithms different implementations of sparse matrices can perform better. See [1] for details.

Returns:

A – Graph adjacency matrix.

Return type:

SciPy sparse array

Notes

For directed graphs, matrix entry i,j corresponds to an edge from i to j.

The matrix entries are populated using the edge attribute held in parameter weight. When an edge does not have that attribute, the value of the entry is 1.

For multiple edges the matrix values are the sums of the edge weights.

When nodelist does not contain every node in G, the adjacency matrix is built from the subgraph of G that is induced by the nodes in nodelist.

The convention used for self-loop edges in graphs is to assign the diagonal matrix entry value to the weight attribute of the edge (or the number 1 if the edge has no weight attribute). If the alternate convention of doubling the edge weight is desired the resulting Scipy sparse matrix can be modified as follows:

>>> G = eg.Graph([(1, 1)])
>>> A = eg.to_scipy_sparse_array(G)
>>> print(A.todense())
[[1]]
>>> A.setdiag(A.diagonal() * 2)
>>> print(A.toarray())
[[2]]

Examples

>>> S = eg.to_scipy_sparse_array(G, nodelist=[0, 1, 2])
>>> print(S.toarray())
[[0 2 0]
 [1 0 0]
 [0 0 4]]

References

[1]

Scipy Dev. References, “Sparse Matrices”, https://docs.scipy.org/doc/scipy/reference/sparse.html

easygraph.utils.convert_to_matrix.to_scipy_sparse_matrix(G, nodelist=None, dtype=None, weight='weight', format='csr')[source]#

Returns the graph adjacency matrix as a SciPy sparse matrix.

Parameters:
  • G (graph) – The EasyGraph graph used to construct the sparse matrix.

  • nodelist (list, optional) – The rows and columns are ordered according to the nodes in nodelist. If nodelist is None, then the ordering is produced by G.nodes().

  • dtype (NumPy data-type, optional) – A valid NumPy dtype used to initialize the array. If None, then the NumPy default is used.

  • weight (string or None optional (default='weight')) – The edge attribute that holds the numerical value used for the edge weight. If None then all edge weights are 1.

  • format (str in {'bsr', 'csr', 'csc', 'coo', 'lil', 'dia', 'dok'}) – The type of the matrix to be returned (default ‘csr’). For some algorithms different implementations of sparse matrices can perform better. See [1] for details.

Returns:

A – Graph adjacency matrix.

Return type:

SciPy sparse matrix

Notes

For directed graphs, matrix entry i,j corresponds to an edge from i to j.

The matrix entries are populated using the edge attribute held in parameter weight. When an edge does not have that attribute, the value of the entry is 1.

For multiple edges the matrix values are the sums of the edge weights.

When nodelist does not contain every node in G, the adjacency matrix is built from the subgraph of G that is induced by the nodes in nodelist.

The convention used for self-loop edges in graphs is to assign the diagonal matrix entry value to the weight attribute of the edge (or the number 1 if the edge has no weight attribute). If the alternate convention of doubling the edge weight is desired the resulting Scipy sparse matrix can be modified as follows:

>>> G = eg.Graph([(1, 1)])
>>> A = eg.to_scipy_sparse_matrix(G)
>>> print(A.todense())
[[1]]
>>> A.setdiag(A.diagonal() * 2)
>>> print(A.todense())
[[2]]

Examples

>>> G.add_edge(1, 0)
0
>>> G.add_edge(2, 2, weight=3)
0
>>> G.add_edge(2, 2)
1
>>> S = eg.to_scipy_sparse_matrix(G, nodelist=[0, 1, 2])
>>> print(S.todense())
[[0 2 0]
 [1 0 0]
 [0 0 4]]

References

[1]

Scipy Dev. References, “Sparse Matrices”, https://docs.scipy.org/doc/scipy/reference/sparse.html