code: def _process_header(self, row):
      self._variables_dict = OrderedDict()
      self._columns = []
      for column, column_value in enumerate(row):
          # Analyze header "NAME[__INDEX][:LABELNAME]"
          # TODO: use regex instead of split....
          try:
              variable_with_index, label = column_value.split(":", 1)
          except:
              label = None
              variable_with_index = column_value
          try:
              variable, index = variable_with_index.split("__", 1)
          except:
              variable = variable_with_index
              index = None
  
          self._columns.append((variable, index, label))
          if index is None:
              self._variables_dict[variable] = {
                  "label": label,
                  "value": None,
              }
          else:
              if variable not in self._variables_dict:
                  self._variables_dict[variable] = []
              self._variables_dict[variable].append(
                  {"label": label, "value": None}
              )
  
imports: import atexit
  import csv
  import os
  import threading
  from collections import OrderedDict, deque
  from time import sleep
  import numpy
  from nnabla.config import nnabla_config
  from nnabla.logger import logger
  from nnabla.utils.communicator_util import current_communicator
  from six.moves import queue
  from .data_source import DataSource
  from .data_source_loader import FileReader, load
label_desc: Use image node_id 2 for calling the CsvDataSource obj's underlying member method code with example usage: obj._process_header(row) without return types