docstr: DBSCAN clustering on cpu or gpu infered automatically. Adds a `_dbscan` column to nodes or edges.
     NOTE: g.transform_dbscan(..) currently unsupported on GPU.
  
  Examples:
  ::
  
      g = graphistry.edges(edf, 'src', 'dst').nodes(ndf, 'node')
  
      # cluster by UMAP embeddings
      kind = 'nodes' | 'edges'
      g2 = g.umap(kind=kind).dbscan(kind=kind)
      print(g2._nodes['_dbscan']) | print(g2._edges['_dbscan'])
  
      # dbscan in umap or featurize API
      g2 = g.umap(dbscan=True, min_dist=1.2, min_samples=2, **kwargs)
      # or, here dbscan is infered from features, not umap embeddings
      g2 = g.featurize(dbscan=True, min_dist=1.2, min_samples=2, **kwargs)
  
      # and via chaining,
      g2 = g.umap().dbscan(min_dist=1.2, min_samples=2, **kwargs)
  
      # cluster by feature embeddings
      g2 = g.featurize().dbscan(**kwargs)
  
      # cluster by a given set of feature column attributes, or with target=True
      g2 = g.featurize().dbscan(cols=['ip_172', 'location', 'alert'], target=False, **kwargs)
  
      # equivalent to above (ie, cols != None and umap=True will still use features dataframe, rather than UMAP embeddings)
      g2 = g.umap().dbscan(cols=['ip_172', 'location', 'alert'], umap=True | False, **kwargs)
  
      g2.plot() # color by `_dbscan` column
  
  Useful:
      Enriching the graph with cluster labels from UMAP is useful for visualizing clusters in the graph by color, size, etc, as well as assessing metrics per cluster, e.g. https://github.com/graphistry/pygraphistry/blob/master/demos/ai/cyber/cyber-redteam-umap-demo.ipynb
  
  Args:
      :min_dist float: The maximum distance between two samples for them to be considered as in the same neighborhood.
      :kind str: 'nodes' or 'edges'
      :cols: list of columns to use for clustering given `g.featurize` has been run, nice way to slice features or targets by fragments of interest, e.g. ['ip_172', 'location', 'ssh', 'warnings']
      :fit_umap_embedding bool: whether to use UMAP embeddings or features dataframe to cluster DBSCAN
      :min_samples: The number of samples in a neighborhood for a point to be considered as a core point. This includes the point itself.
      :target: whether to use the target column as the clustering feature
docstr_tok: ["DBSCAN","clustering","on","cpu","or","gpu","infered","automatically",".","Adds","a","`","_dbscan","`","column","to","nodes","or","edges",".","NOTE",":","g.transform_dbscan","(","..",")","currently","unsupported","on","GPU",".","Examples",":",":",":","g","=","graphistry.edges","(","edf",",","'src","'",",","'dst","'",")",".nodes","(","ndf",",","'node","'",")","#","cluster","by","UMAP","embeddings","kind","=","'nodes","'","|","'edges'","g2","=","g.umap","(","kind=kind",")",".dbscan","(","kind=kind",")","print","(","g2._nodes","[","'_dbscan","'","]",")","|","print","(","g2._edges","[","'_dbscan","'","]",")","#","dbscan","in","umap","or","featurize","API","g2","=","g.umap","(","dbscan=True",",","min_dist=1.2",",","min_samples=2",",","*","*","kwargs",")","#","or",",","here","dbscan","is","infered","from","features",",","not","umap","embeddings","g2","=","g.featurize","(","dbscan=True",",","min_dist=1.2",",","min_samples=2",",","*","*","kwargs",")","#","and","via","chaining",",","g2","=","g.umap","(",")",".dbscan","(","min_dist=1.2",",","min_samples=2",",","*","*","kwargs",")","#","cluster","by","feature","embeddings","g2","=","g.featurize","(",")",".dbscan","(","*","*","kwargs",")","#","cluster","by","a","given","set","of","feature","column","attributes",",","or","with","target=True","g2","=","g.featurize","(",")",".dbscan","(","cols=","[","'ip_172","'",",","'location","'",",","'alert","'","]",",","target=False",",","*","*","kwargs",")","#","equivalent","to","above","(","ie",",","cols","!","=","None","and","umap=True","will","still","use","features","dataframe",",","rather","than","UMAP","embeddings",")","g2","=","g.umap","(",")",".dbscan","(","cols=","[","'ip_172","'",",","'location","'",",","'alert","'","]",",","umap=True","|","False",",","*","*","kwargs",")","g2.plot","(",")","#","color","by","`","_dbscan","`","column","Useful",":","Enriching","the","graph","with","cluster","labels","from","UMAP","is","useful","for","visualizing","clusters","in","the","graph","by","color",",","size",",","etc",",","as","well","as","assessing","metrics","per","cluster",",","e.g",".","https",":","\/\/github.com\/graphistry\/pygraphistry\/blob\/master\/demos\/ai\/cyber\/cyber-redteam-umap-demo.ipynb","Args",":",":","min_dist","float",":","The","maximum","distance","between","two","samples","for","them","to","be","considered","as","in","the","same","neighborhood",".",":","kind","str",":","'nodes","'","or","'edges'",":","cols",":","list","of","columns","to","use","for","clustering","given","`","g.featurize","`","has","been","run",",","nice","way","to","slice","features","or","targets","by","fragments","of","interest",",","e.g",".","[","'ip_172","'",",","'location","'",",","'ssh","'",",","'warnings","'","]",":","fit_umap_embedding","bool",":","whether","to","use","UMAP","embeddings","or","features","dataframe","to","cluster","DBSCAN",":","min_samples",":","The","number","of","samples","in","a","neighborhood","for","a","point","to","be","considered","as","a","core","point",".","This","includes","the","point","itself",".",":","target",":","whether","to","use","the","target","column","as","the","clustering","feature"]
code: def dbscan(
      self,
      min_dist: float = 0.2,
      min_samples: int = 1,
      cols: Optional[Union[List, str]] = None,
      kind: str = "nodes",
      fit_umap_embedding: bool = True,
      target: bool = False,
      verbose: bool = False,
      engine_dbscan: str = "sklearn",
      *args,
      **kwargs,
  ):
      """DBSCAN clustering on cpu or gpu infered automatically. Adds a `_dbscan` column to nodes or edges.
         NOTE: g.transform_dbscan(..) currently unsupported on GPU.
  
      Examples:
      ::
  
          g = graphistry.edges(edf, 'src', 'dst').nodes(ndf, 'node')
  
          # cluster by UMAP embeddings
          kind = 'nodes' | 'edges'
          g2 = g.umap(kind=kind).dbscan(kind=kind)
          print(g2._nodes['_dbscan']) | print(g2._edges['_dbscan'])
  
          # dbscan in umap or featurize API
          g2 = g.umap(dbscan=True, min_dist=1.2, min_samples=2, **kwargs)
          # or, here dbscan is infered from features, not umap embeddings
          g2 = g.featurize(dbscan=True, min_dist=1.2, min_samples=2, **kwargs)
  
          # and via chaining,
          g2 = g.umap().dbscan(min_dist=1.2, min_samples=2, **kwargs)
  
          # cluster by feature embeddings
          g2 = g.featurize().dbscan(**kwargs)
  
          # cluster by a given set of feature column attributes, or with target=True
          g2 = g.featurize().dbscan(cols=['ip_172', 'location', 'alert'], target=False, **kwargs)
  
          # equivalent to above (ie, cols != None and umap=True will still use features dataframe, rather than UMAP embeddings)
          g2 = g.umap().dbscan(cols=['ip_172', 'location', 'alert'], umap=True | False, **kwargs)
  
          g2.plot() # color by `_dbscan` column
  
      Useful:
          Enriching the graph with cluster labels from UMAP is useful for visualizing clusters in the graph by color, size, etc, as well as assessing metrics per cluster, e.g. https://github.com/graphistry/pygraphistry/blob/master/demos/ai/cyber/cyber-redteam-umap-demo.ipynb
  
      Args:
          :min_dist float: The maximum distance between two samples for them to be considered as in the same neighborhood.
          :kind str: 'nodes' or 'edges'
          :cols: list of columns to use for clustering given `g.featurize` has been run, nice way to slice features or targets by fragments of interest, e.g. ['ip_172', 'location', 'ssh', 'warnings']
          :fit_umap_embedding bool: whether to use UMAP embeddings or features dataframe to cluster DBSCAN
          :min_samples: The number of samples in a neighborhood for a point to be considered as a core point. This includes the point itself.
          :target: whether to use the target column as the clustering feature
  
      """
  
      res = self.bind()
      res = res._cluster_dbscan(
          res,
          kind=kind,
          cols=cols,
          fit_umap_embedding=fit_umap_embedding,
          target=target,
          min_dist=min_dist,
          min_samples=min_samples,
          engine_dbscan=engine_dbscan,
          verbose=verbose,
          *args,
          **kwargs,
      )
  
      return res
  
imports: import logging
  import pandas
  import numpy
  from typing import Any, List, Union, TYPE_CHECKING, Tuple, Optional
  from typing_extensions import Literal
  from collections import Counter
  from graphistry.Plottable import Plottable
  from graphistry.constants import CUML, UMAP_LEARN, DBSCAN
  from graphistry.features import ModelDict
  from graphistry.feature_utils import get_matrix_by_column_parts
label_desc: Use image node_id 3 for calling the ClusterMixin obj's underlying member method code with example usage: obj.dbscan(min_dist, min_samples, cols, kind, fit_umap_embedding, target, verbose, engine_dbscan) and returns: res