class_docstr: For heterogeneous graphs, it performs uniform random walks based on given metapaths. Optional
  parameters default to using the values passed in during construction.
  
  .. seealso::
  
     Examples using this random walk:
  
     - `Metapath2Vec link prediction <https://stellargraph.readthedocs.io/en/stable/demos/link-prediction/metapath2vec-link-prediction.html>`__
     - `Metapath2Vec unsupervised representation learning <https://stellargraph.readthedocs.io/en/stable/demos/embeddings/metapath2vec-embeddings.html>`__
  
     Related functionality:
  
     - :class:`.UnsupervisedSampler` for transforming random walks into links for unsupervised training of link prediction models
     - Other random walks: :class:`.UniformRandomWalk`, :class:`.BiasedRandomWalk`, :class:`.TemporalRandomWalk`.
  
  
  Args:
      graph (StellarGraph): Graph to traverse
      n (int, optional): Total number of random walks per root node
      length (int, optional): Maximum length of each random walk
      metapaths (list of list, optional): List of lists of node labels that specify a metapath schema, e.g.,
          [['Author', 'Paper', 'Author'], ['Author, 'Paper', 'Venue', 'Paper', 'Author']] specifies two metapath
          schemas of length 3 and 5 respectively.
      seed (int, optional): Random number generator seed
class_docstr_tok: ["For","heterogeneous","graphs",",","it","performs","uniform","random","walks","based","on","given","metapaths",".","Optional","parameters","default","to","using","the","values","passed","in","during","construction",".","..","seealso",":",":","Examples","using","this","random","walk",":","-","`","Metapath2Vec","link","prediction","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/link-prediction\/metapath2vec-link-prediction.html",">","`","__","-","`","Metapath2Vec","unsupervised","representation","learning","<","https",":","\/\/stellargraph.readthedocs.io\/en\/stable\/demos\/embeddings\/metapath2vec-embeddings.html",">","`","__","Related","functionality",":","-",":","class",":","`",".UnsupervisedSampler","`","for","transforming","random","walks","into","links","for","unsupervised","training","of","link","prediction","models","-","Other","random","walks",":",":","class",":","`",".UniformRandomWalk","`",",",":","class",":","`",".BiasedRandomWalk","`",",",":","class",":","`",".TemporalRandomWalk","`",".","Args",":","graph","(","StellarGraph",")",":","Graph","to","traverse","n","(","int",",","optional",")",":","Total","number","of","random","walks","per","root","node","length","(","int",",","optional",")",":","Maximum","length","of","each","random","walk","metapaths","(","list","of","list",",","optional",")",":","List","of","lists","of","node","labels","that","specify","a","metapath","schema",",","e.g.",",","[","[","'Author","'",",","'Paper","'",",","'Author","'","]",",","[","'Author",",","'Paper","'",",","'Venue","'",",","'Paper","'",",","'Author","'","]","]","specifies","two","metapath","schemas","of","length","3","and","5","respectively",".","seed","(","int",",","optional",")",":","Random","number","generator","seed"]
docstr: Performs metapath-driven uniform random walks on heterogeneous graphs.
  
  Args:
      nodes (list): The root nodes as a list of node IDs
      n (int, optional): Total number of random walks per root node
      length (int, optional): Maximum length of each random walk
      metapaths (list of list, optional): List of lists of node labels that specify a metapath schema, e.g.,
          [['Author', 'Paper', 'Author'], ['Author, 'Paper', 'Venue', 'Paper', 'Author']] specifies two metapath
          schemas of length 3 and 5 respectively.
      seed (int, optional): Random number generator seed; default is None
  
  Returns:
      List of lists of nodes ids for each of the random walks generated
docstr_tok: ["Performs","metapath-driven","uniform","random","walks","on","heterogeneous","graphs",".","Args",":","nodes","(","list",")",":","The","root","nodes","as","a","list","of","node","IDs","n","(","int",",","optional",")",":","Total","number","of","random","walks","per","root","node","length","(","int",",","optional",")",":","Maximum","length","of","each","random","walk","metapaths","(","list","of","list",",","optional",")",":","List","of","lists","of","node","labels","that","specify","a","metapath","schema",",","e.g.",",","[","[","'Author","'",",","'Paper","'",",","'Author","'","]",",","[","'Author",",","'Paper","'",",","'Venue","'",",","'Paper","'",",","'Author","'","]","]","specifies","two","metapath","schemas","of","length","3","and","5","respectively",".","seed","(","int",",","optional",")",":","Random","number","generator","seed",";","default","is","None","Returns",":","List","of","lists","of","nodes","ids","for","each","of","the","random","walks","generated"]
code: def run(
      self, nodes, *, n=None, length=None, metapaths=None, seed=None
  ):
      """
      Performs metapath-driven uniform random walks on heterogeneous graphs.
  
      Args:
          nodes (list): The root nodes as a list of node IDs
          n (int, optional): Total number of random walks per root node
          length (int, optional): Maximum length of each random walk
          metapaths (list of list, optional): List of lists of node labels that specify a metapath schema, e.g.,
              [['Author', 'Paper', 'Author'], ['Author, 'Paper', 'Venue', 'Paper', 'Author']] specifies two metapath
              schemas of length 3 and 5 respectively.
          seed (int, optional): Random number generator seed; default is None
  
      Returns:
          List of lists of nodes ids for each of the random walks generated
      """
      n = _default_if_none(n, self.n, "n")
      length = _default_if_none(length, self.length, "length")
      metapaths = _default_if_none(
          metapaths, self.metapaths, "metapaths"
      )
      self._validate_walk_params(nodes, n, length)
      self._check_metapath_values(metapaths)
      rs, _ = self._get_random_state(seed)
  
      nodes = self.graph.node_ids_to_ilocs(nodes)
  
      walks = []
  
      for node in nodes:
          # retrieve node type
          label = self.graph.node_type(node, use_ilocs=True)
          filtered_metapaths = [
              metapath
              for metapath in metapaths
              if len(metapath) > 0 and metapath[0] == label
          ]
  
          for metapath in filtered_metapaths:
              # augment metapath to be length long
              # if (
              #     len(metapath) == 1
              # ):  # special case for random walks like in a homogeneous graphs
              #     metapath = metapath * length
              # else:
              metapath = metapath[1:] * (
                  (length // (len(metapath) - 1)) + 1
              )
              for _ in range(n):
                  walk = (
                      []
                  )  # holds the walk data for this walk; first node is the starting node
                  current_node = node
                  for d in range(length):
                      walk.append(current_node)
                      # d+1 can also be used to index metapath to retrieve the node type for the next step in the walk
                      neighbours = self.graph.neighbor_arrays(
                          current_node, use_ilocs=True
                      )
                      # filter these by node type
                      neighbour_types = self.graph.node_type(
                          neighbours, use_ilocs=True
                      )
                      neighbours = [
                          neigh
                          for neigh, neigh_type in zip(
                              neighbours, neighbour_types
                          )
                          if neigh_type == metapath[d]
                      ]
  
                      if len(neighbours) == 0:
                          # if no neighbours of the required type as dictated by the metapath exist, then stop.
                          break
                      # select one of the neighbours uniformly at random
                      current_node = rs.choice(
                          neighbours
                      )  # the next node in the walk
  
                  walks.append(
                      list(self.graph.node_ilocs_to_ids(walk))
                  )  # store the walk
  
      return walks
  
imports: import numpy
  import warnings
  from collections import defaultdict, deque
  from scipy import stats
  from scipy.special import softmax
  from ..core.schema import GraphSchema
  from ..core.graph import StellarGraph
  from ..core.utils import is_real_iterable
  from ..core.validation import require_integer_in_range, comma_sep
  from ..random import random_state
  from abc import ABC, abstractmethod
label_desc: Use image node_id 2 for calling the UniformRandomMetaPathWalk obj's underlying member method code with example usage: obj.run(nodes) and returns: walks