class_docstr: Class for generating training and test data for link prediction in graphs.
  
  The class requires as input a graph (in networkx format) and a percentage as a function of the total number of edges
  in the given graph of the number of positive and negative edges to sample. For heterogeneous graphs, the caller
  can also specify the type of edge and an edge property to split on. In the latter case, only a date property
  can be used and it must be in the format ``dd/mm/yyyy``. A date to be used as a threshold value such that only
  edges that have date after the threshold must be given. This effects only the sampling of positive edges.
  
  Negative edges are sampled at random by (for 'global' method) selecting two nodes in the graph and
  then checking if these edges are connected or not. If not, the pair of nodes is considered a negative sample.
  Otherwise, it is discarded and the process repeats. Alternatively, negative edges are sampled (for 'local' method)
  using DFS search at a distance from the source node (selected at random from all nodes in the graph)
  sampled according to a given set of probabilities.
  
  Positive edges can be sampled so that when they are subsequently removed from the graph, the reduced graph is either
  guaranteed, or not guaranteed, to remain connected. In the former case, graph connectivity is maintained by first
  calculating the minimum spanning tree. The edges that belong to the minimum spanning tree are protected from
  removal, and therefore cannot be sampled for the training set. The edges that do not belong to the minimum spanning
  tree are then sampled uniformly at random, until the required number of positive edges have been sampled for the
  training set. In the latter case, when connectedness of the reduced graph is not guaranteed, positive edges are
  sampled uniformly at random from all the edges in the graph, regardless of whether they belong to the spanning tree
  (which is not calculated in this case).
  
  Args:
      g (StellarGraph or networkx object): The graph to sample edges from.
      g_master (StellarGraph or networkx object): The graph representing the original dataset and a superset of the
          graph g. If it is not None, then when positive and negative edges are sampled, care is taken to make sure
          that a true positive edge is not sampled as a negative edge.
class_docstr_tok: ["Class","for","generating","training","and","test","data","for","link","prediction","in","graphs",".","The","class","requires","as","input","a","graph","(","in","networkx","format",")","and","a","percentage","as","a","function","of","the","total","number","of","edges","in","the","given","graph","of","the","number","of","positive","and","negative","edges","to","sample",".","For","heterogeneous","graphs",",","the","caller","can","also","specify","the","type","of","edge","and","an","edge","property","to","split","on",".","In","the","latter","case",",","only","a","date","property","can","be","used","and","it","must","be","in","the","format","``","dd\/mm\/yyyy","``",".","A","date","to","be","used","as","a","threshold","value","such","that","only","edges","that","have","date","after","the","threshold","must","be","given",".","This","effects","only","the","sampling","of","positive","edges",".","Negative","edges","are","sampled","at","random","by","(","for","'global","'","method",")","selecting","two","nodes","in","the","graph","and","then","checking","if","these","edges","are","connected","or","not",".","If","not",",","the","pair","of","nodes","is","considered","a","negative","sample",".","Otherwise",",","it","is","discarded","and","the","process","repeats",".","Alternatively",",","negative","edges","are","sampled","(","for","'local","'","method",")","using","DFS","search","at","a","distance","from","the","source","node","(","selected","at","random","from","all","nodes","in","the","graph",")","sampled","according","to","a","given","set","of","probabilities",".","Positive","edges","can","be","sampled","so","that","when","they","are","subsequently","removed","from","the","graph",",","the","reduced","graph","is","either","guaranteed",",","or","not","guaranteed",",","to","remain","connected",".","In","the","former","case",",","graph","connectivity","is","maintained","by","first","calculating","the","minimum","spanning","tree",".","The","edges","that","belong","to","the","minimum","spanning","tree","are","protected","from","removal",",","and","therefore","can","not","be","sampled","for","the","training","set",".","The","edges","that","do","not","belong","to","the","minimum","spanning","tree","are","then","sampled","uniformly","at","random",",","until","the","required","number","of","positive","edges","have","been","sampled","for","the","training","set",".","In","the","latter","case",",","when","connectedness","of","the","reduced","graph","is","not","guaranteed",",","positive","edges","are","sampled","uniformly","at","random","from","all","the","edges","in","the","graph",",","regardless","of","whether","they","belong","to","the","spanning","tree","(","which","is","not","calculated","in","this","case",")",".","Args",":","g","(","StellarGraph","or","networkx","object",")",":","The","graph","to","sample","edges","from",".","g_master","(","StellarGraph","or","networkx","object",")",":","The","graph","representing","the","original","dataset","and","a","superset","of","the","graph","g.","If","it","is","not","None",",","then","when","positive","and","negative","edges","are","sampled",",","care","is","taken","to","make","sure","that","a","true","positive","edge","is","not","sampled","as","a","negative","edge","."]
docstr: Reduces the graph self.g_train by a factor p by removing existing edges not on minedges list such that
  the reduced tree remains connected. Edge type is ignored and all edges are treated equally.
  
  Args:
      minedges (list): Minimum spanning tree edges that cannot be removed.
      p (float): Factor by which to reduce the size of the graph.
  
  Returns:
      (list) Returns the list of edges removed from self.g_train (also modifies self.g_train by removing the
      said edges)
docstr_tok: ["Reduces","the","graph","self.g_train","by","a","factor","p","by","removing","existing","edges","not","on","minedges","list","such","that","the","reduced","tree","remains","connected",".","Edge","type","is","ignored","and","all","edges","are","treated","equally",".","Args",":","minedges","(","list",")",":","Minimum","spanning","tree","edges","that","can","not","be","removed",".","p","(","float",")",":","Factor","by","which","to","reduce","the","size","of","the","graph",".","Returns",":","(","list",")","Returns","the","list","of","edges","removed","from","self.g_train","(","also","modifies","self.g_train","by","removing","the","said","edges",")"]
code: def _reduce_graph(self, minedges, p=0.5):
      """
      Reduces the graph self.g_train by a factor p by removing existing edges not on minedges list such that
      the reduced tree remains connected. Edge type is ignored and all edges are treated equally.
  
      Args:
          minedges (list): Minimum spanning tree edges that cannot be removed.
          p (float): Factor by which to reduce the size of the graph.
  
      Returns:
          (list) Returns the list of edges removed from self.g_train (also modifies self.g_train by removing the
          said edges)
      """
      # copy the original graph and start over in case this is not the first time
      # reduce_graph has been called.
      self.g_train = self.g.copy()
  
      # For multigraphs we should probably use keys
      use_keys_in_edges = self.g.is_multigraph()
  
      # For NX 1.x/2.x compatibilty we need to match length of minedges
      if len(minedges) > 0:
          use_keys_in_edges = len(next(iter(minedges))) == 3
  
      if use_keys_in_edges:
          all_edges = list(self.g_train.edges(keys=True))
      else:
          all_edges = list(self.g_train.edges())
  
      num_edges_to_remove = int(self.g_train.number_of_edges() * p)
  
      if num_edges_to_remove > (
          self.g_train.number_of_edges() - len(self.minedges)
      ):
          raise ValueError(
              "Not enough positive edges to sample after reserving {} number of edges for maintaining graph connectivity. Consider setting keep_connected=False.".format(
                  len(self.minedges)
              )
          )
  
      # shuffle the edges
      self._random.shuffle(all_edges)
      # iterate over the list of edges and for each edge if the edge is not in minedges, remove it from the graph
      # until num_edges_to_remove edges have been removed and the graph reduced to p of its original size
      count = 0
      removed_edges = []
      for edge in all_edges:
          if edge not in minedges:
              removed_edges.append(
                  (edge[0], edge[1], 1)
              )  # the last entry is the label
              self.g_train.remove_edge(*edge)
  
              count += 1
          if count == num_edges_to_remove:
              return removed_edges
  
imports: import datetime
  import warnings
  import networkx
  import pandas
  import numpy
  from math import isclose
  from ..core import StellarGraph
  from ..globalvar import FEATURE_ATTR_NAME
label_desc: Use image node_id 9 for calling the EdgeSplitter obj's underlying member method code with example usage: obj._reduce_graph(minedges, p) and returns: removed_edges