code: def fit(
      cls,
      column_name: str,
      line: List[str],
      is_label: bool,
      custom_dtype: Optional[DataTypes],
      custom_mapping: Optional[Dict[str, int]],
      default_value: Optional[int],
  ) -> "Converter":
      self: Converter = cls()
      self.column_name = column_name
      self.is_label = is_label
      not_empty = [e for e in line if e]
      num_empty = len(line) - len(not_empty)
      self.has_empty = num_empty > 0
      self.default_value = default_value
      try:
          array = np.array(not_empty, np.float64)
      except ValueError:
          if (
              custom_dtype is not None
              and custom_dtype != DataTypes.STRING
          ):
              print_warning(
                  f"`custom_dtype` is set to '{custom_dtype}' but corresponding "
                  "column cannot cast it, fallback to 'string'"
              )
          self.has_nan = False
          self.dtype = DataTypes.STRING
          if custom_mapping is not None:
              self._fit_with_custom_mapping(
                  line, column_name, custom_mapping
              )
          else:
              counter = Counter(line)
              filtered_counter: Counter = Counter()
              for e, count in counter.most_common():
                  if e.lower() == "nan":
                      e = "nan"
                      self.has_nan = True
                  filtered_counter[e] += count
              most_common = filtered_counter.most_common()
              # smaller index -> more frequent
              self.mapping = {
                  k: i for i, (k, _) in enumerate(most_common)
              }
              self.counter = dict(filtered_counter)
          return self
      nan_mask = np.isnan(array)
      not_nan_mask = ~nan_mask
      not_nan = array[not_nan_mask]
      self.has_nan = len(array) != len(not_nan)
      int_array = not_nan.astype(int)
      int_float_array = int_array.astype(np.float64)
      if custom_dtype == DataTypes.FLOAT or not np.allclose(
          not_nan, int_float_array
      ):
          self.mapping = {}
          self.counter = {}
          self.dtype = DataTypes.FLOAT
      else:
          self.dtype = DataTypes.INT
          if custom_mapping is not None:
              self._fit_with_custom_mapping(
                  line, column_name, custom_mapping
              )
          else:
              if self.has_nan:
                  int_array = int_array[not_nan_mask]
              unique, counts = np.unique(int_array, return_counts=True)
              self.mapping = {}
              self.counter = {}
              unique_list = unique.tolist()
              counts_list = counts.tolist()
              for i, idx in enumerate(
                  np.argsort(counts).tolist()[::-1]
              ):
                  str_original = str(unique_list[idx])
                  self.mapping[str_original] = i
                  self.counter[str_original] = counts_list[idx]
      if self.dtype == DataTypes.INT:
          if self.has_nan:
              self.mapping["nan"] = len(self.mapping)
              self.counter["nan"] = nan_mask.sum().item()
          if self.has_empty:
              self.mapping[""] = len(self.mapping)
              self.counter[""] = num_empty
      return self
  
imports: import csv
  import numpy
  from typing import Any
  from typing import Dict
  from typing import List
  from typing import Tuple
  from typing import Union
  from typing import Optional
  from pathlib import Path
  from collections import Counter
  from dataclasses import dataclass
  from cftool.misc import print_info
  from cftool.misc import print_warning
  from cftool.misc import shallow_copy_dict
  from cftool.misc import ISerializable
  from cftool.misc import PureFromInfoMixin
  from cftool.array import is_float
  from ....schema import DataTypes
  from ....schema import DataBundle
  from ....schema import TDataBundleItem
  from ....schema import INoInitDataBlock
label_desc: Use image node_id 3 for calling the Converter obj's underlying member method code with example usage: obj.fit(cls, column_name, line, is_label, custom_dtype, custom_mapping, default_value) and returns: self, self