class_docstr: Class to do biased second order random walks.
  
  Args:
      walk_length (int): Number of random walks.
      walk_number (int): Number of nodes in truncated walk.
      p (float): Return parameter (1/p transition probability) to move towards previous node.
      q (float): In-out parameter (1/q transition probability) to move away from previous node.
class_docstr_tok: ["Class","to","do","biased","second","order","random","walks",".","Args",":","walk_length","(","int",")",":","Number","of","random","walks",".","walk_number","(","int",")",":","Number","of","nodes","in","truncated","walk",".","p","(","float",")",":","Return","parameter","(","1\/p","transition","probability",")","to","move","towards","previous","node",".","q","(","float",")",":","In-out","parameter","(","1\/q","transition","probability",")","to","move","away","from","previous","node","."]
docstr: Doing a single truncated second order random walk from a source node.
  
  Arg types:
      * **node** *(int)* - The source node of the random walk.
  
  Return types:
      * **walk** *(list of strings)* - A single truncated random walk.
docstr_tok: ["Doing","a","single","truncated","second","order","random","walk","from","a","source","node",".","Arg","types",":","*","*","*","node","*","*","*","(","int",")","*","-","The","source","node","of","the","random","walk",".","Return","types",":","*","*","*","walk","*","*","*","(","list","of","strings",")","*","-","A","single","truncated","random","walk","."]
code: def do_walk(self, node: int) -> List[str]:
      """
      Doing a single truncated second order random walk from a source node.
  
      Arg types:
          * **node** *(int)* - The source node of the random walk.
  
      Return types:
          * **walk** *(list of strings)* - A single truncated random walk.
      """
      walk = [node]
      previous_node = None
      previous_node_neighbors = []
      for _ in range(self.walk_length - 1):
          current_node = walk[-1]
          edges = self.edge_fn(current_node)
          current_node_neighbors = np.array([edge[1] for edge in edges])
  
          weights = self.weight_fn(edges)
          probability = np.piecewise(
              weights,
              [
                  current_node_neighbors == previous_node,
                  np.isin(
                      current_node_neighbors, previous_node_neighbors
                  ),
              ],
              [
                  lambda w: w / self.p,
                  lambda w: w / 1,
                  lambda w: w / self.q,
              ],
          )
  
          norm_probability = probability / sum(probability)
          selected = np.random.choice(
              current_node_neighbors, 1, p=norm_probability
          )[0]
          walk.append(selected)
  
          previous_node_neighbors = current_node_neighbors
          previous_node = current_node
  
      walk = [str(w) for w in walk]
      return walk
  
imports: import random
  from functools import partial
  from typing import List, Callable
  import numpy
  import networkx
label_desc: Use image node_id 2 for calling the BiasedRandomWalker obj's underlying member method code with example usage: obj.do_walk(node) and returns: walk