Source code for xgi.convert.higher_order_network

"""Methods for converting to higher-order network objects."""

from copy import deepcopy

import pandas as pd
from numpy import matrix, ndarray
from scipy.sparse import (
    coo_array,
    coo_matrix,
    csc_array,
    csc_matrix,
    csr_array,
    csr_matrix,
    lil_array,
    lil_matrix,
)

from ..core import DiHypergraph, Hypergraph, SimplicialComplex
from ..exception import XGIError
from ..generators import empty_dihypergraph, empty_hypergraph, empty_simplicial_complex
from .hyperedges import from_hyperedge_dict, from_hyperedge_list
from .incidence import from_incidence_matrix
from .pandas import from_bipartite_pandas_dataframe
from .simplex import from_simplex_dict

__all__ = [
    "to_hypergraph",
    "to_dihypergraph",
    "to_simplicial_complex",
]


[docs]def to_hypergraph(data, create_using=None): """Make a hypergraph from a known data structure. The preferred way to call this is automatically from the class constructor. Parameters ---------- data : object to be converted Current known types are: * a Hypergraph object * a SimplicialComplex object * list-of-iterables * dict-of-iterables * Pandas DataFrame (bipartite edgelist) * numpy matrix * numpy ndarray * scipy sparse matrix create_using : Hypergraph constructor, optional (default=Hypergraph) Hypergraph type to create. If hypergraph instance, then cleared before populated. Returns ------- Hypergraph object A hypergraph constructed from the data See Also -------- from_max_simplices : Constructs a hypergraph from the maximal simplices of a simplicial complex. """ if data is None: return empty_hypergraph(create_using) elif isinstance(data, Hypergraph) and not isinstance(data, SimplicialComplex): H = empty_hypergraph(create_using) H.add_nodes_from((n, attr) for n, attr in data.nodes.items()) ee = data.edges H.add_edges_from((ee.members(e), e, deepcopy(attr)) for e, attr in ee.items()) H._hypergraph = deepcopy(data._hypergraph) return H elif isinstance(data, DiHypergraph): H = empty_hypergraph(create_using) H.add_nodes_from((n, attr) for n, attr in data.nodes.items()) ee = data.edges H.add_edges_from((ee.members(e), e, deepcopy(attr)) for e, attr in ee.items()) H._hypergraph = deepcopy(data._hypergraph) if not isinstance(create_using, DiHypergraph): return H elif isinstance(data, SimplicialComplex): H = empty_hypergraph(create_using) H.add_nodes_from((n, attr) for n, attr in data.nodes.items()) ee = data.edges H.add_edges_from((ee.members(e), e, deepcopy(attr)) for e, attr in ee.items()) H._hypergraph = deepcopy(data._hypergraph) return H elif isinstance(data, list): # edge list result = from_hyperedge_list(data, create_using) if not isinstance(create_using, Hypergraph): return result elif isinstance(data, pd.DataFrame): result = from_bipartite_pandas_dataframe(data, create_using) if not isinstance(create_using, Hypergraph): return result elif isinstance(data, dict): # edge dict in the form we need result = from_hyperedge_dict(data, create_using) if not isinstance(create_using, Hypergraph): return result elif isinstance( data, ( ndarray, matrix, csr_array, csc_array, coo_array, lil_array, csr_matrix, csc_matrix, coo_matrix, lil_matrix, ), ): from_incidence_matrix(data, create_using) else: raise XGIError("Input data has unsupported type.")
[docs]def to_dihypergraph(data, create_using=None): """Make a dihypergraph from a known data structure. The preferred way to call this is automatically from the class constructor. Parameters ---------- data : object to be converted Current known types are: * a DiHypergraph object * a SimplicialComplex object * list-of-iterables * dict-of-iterables * Pandas DataFrame (bipartite edgelist) * numpy matrix * numpy ndarray * scipy sparse matrix create_using : Hypergraph constructor, optional (default=Hypergraph) Hypergraph type to create. If hypergraph instance, then cleared before populated. Returns ------- Hypergraph object A hypergraph constructed from the data """ if data is None: return empty_dihypergraph(create_using) elif isinstance(data, DiHypergraph): H = empty_dihypergraph(create_using) H.add_nodes_from((n, attr) for n, attr in data.nodes.items()) ee = data.edges H.add_edges_from((ee.dimembers(e), e, deepcopy(attr)) for e, attr in ee.items()) H._hypergraph = deepcopy(data._hypergraph) if not isinstance(create_using, DiHypergraph): return H elif isinstance(data, list): # edge list result = from_hyperedge_list(data, create_using) if not isinstance(create_using, DiHypergraph): return result elif isinstance(data, dict): # edge dict in the form we need result = from_hyperedge_dict(data, create_using) if not isinstance(create_using, DiHypergraph): return result else: raise XGIError("Input data has unsupported type.")
from ..generators import empty_simplicial_complex
[docs]def to_simplicial_complex(data, create_using=None): """Make a hypergraph from a known data structure. The preferred way to call this is automatically from the class constructor. Parameters ---------- data : object to be converted Current known types are: * a SimplicialComplex object * a Hypergraph object * list-of-iterables * dict-of-iterables * Pandas DataFrame (bipartite edgelist) * numpy matrix * numpy ndarray * scipy sparse matrix create_using : Hypergraph graph constructor, optional (default=Hypergraph) Hypergraph type to create. If hypergraph instance, then cleared before populated. Returns ------- Hypergraph object A hypergraph constructed from the data """ if data is None: return empty_simplicial_complex(create_using) elif isinstance(data, SimplicialComplex): H = empty_simplicial_complex(create_using) H.add_nodes_from((n, attr) for n, attr in data.nodes.items()) ee = data.edges H.add_simplices_from( (ee.members(e), e, deepcopy(attr)) for e, attr in ee.items() ) H._hypergraph = deepcopy(data._hypergraph) return H elif isinstance(data, Hypergraph): H = empty_simplicial_complex(create_using) H.add_nodes_from((n, attr) for n, attr in data.nodes.items()) ee = data.edges H.add_simplices_from( (ee.members(e), e, deepcopy(attr)) for e, attr in ee.items() ) return H elif isinstance(data, list): # edge list result = from_hyperedge_list(data, create_using) if not isinstance(create_using, SimplicialComplex): return to_simplicial_complex(result) elif isinstance(data, pd.DataFrame): result = from_bipartite_pandas_dataframe(data, create_using) if not isinstance(create_using, SimplicialComplex): return to_simplicial_complex(result) elif isinstance(data, dict): result = from_simplex_dict(data, create_using) if not isinstance(create_using, SimplicialComplex): return to_simplicial_complex(result) elif isinstance( data, ( ndarray, matrix, csr_array, csc_array, coo_array, lil_array, csr_matrix, csc_matrix, coo_matrix, lil_matrix, ), ): # incidence matrix raise XGIError( "Not implemented: construction of a SimplicialComplex from incidence matrix" ) else: raise XGIError("Input data has unsupported type.")