code: def from_numpy_lasso(
      X: np.ndarray,
      beta: float,
      max_iter: int = 100,
      h_tol: float = 1e-8,
      w_threshold: float = 0.0,
      tabu_edges: List[Tuple[int, int]] = None,
      tabu_parent_nodes: List[int] = None,
      tabu_child_nodes: List[int] = None,
  ) -> StructureModel:
      """
      Learn the `StructureModel`, the graph structure with lasso regularisation
      describing conditional dependencies between variables in data presented as a numpy array.
  
      Based on DAGs with NO TEARS.
      @inproceedings{zheng2018dags,
          author = {Zheng, Xun and Aragam, Bryon and Ravikumar, Pradeep and Xing, Eric P.},
          booktitle = {Advances in Neural Information Processing Systems},
          title = {{DAGs with NO TEARS: Continuous Optimization for Structure Learning}},
          year = {2018},
          codebase = {https://github.com/xunzheng/notears}
      }
  
      Args:
          X: 2d input data, axis=0 is data rows, axis=1 is data columns. Data must be row oriented.
          beta: Constant that multiplies the lasso term.
          max_iter: max number of dual ascent steps during optimisation.
          h_tol: exit if h(W) < h_tol (as opposed to strict definition of 0).
          w_threshold: fixed threshold for absolute edge weights.
          tabu_edges: list of edges(from, to) not to be included in the graph.
          tabu_parent_nodes: list of nodes banned from being a parent of any other nodes.
          tabu_child_nodes: list of nodes banned from being a child of any other nodes.
  
      Returns:
          StructureModel: a graph of conditional dependencies between data variables.
  
      Raises:
          ValueError: If X does not contain data.
      """
  
      # n examples, d properties
      _, d = X.shape
  
      _assert_all_finite(X)
  
      bnds = [
          (0, 0)
          if i == j
          else (0, 0)
          if tabu_edges is not None and (i, j) in tabu_edges
          else (0, 0)
          if tabu_parent_nodes is not None and i in tabu_parent_nodes
          else (0, 0)
          if tabu_child_nodes is not None and j in tabu_child_nodes
          else (0, None)
          for i in range(d)
          for j in range(d)
      ] * 2
  
      return _learn_structure_lasso(
          X, beta, bnds, max_iter, h_tol, w_threshold
      )
  
file_path: causalnex/causalnex/structure/notears.py
imports: import logging
  import warnings
  from copy import deepcopy
  from typing import List, Tuple
  import numpy
  import pandas
  import scipy.linalg
  import scipy.optimize
  from causalnex.structure.structuremodel import StructureModel
label_desc: Use image node_id 2 for calling a global function with example usage: from_numpy_lasso(X, beta, max_iter, h_tol, w_threshold, tabu_edges, tabu_parent_nodes, tabu_child_nodes) and returns: _learn_structure_lasso