code: def _read(self) -> Iterator[Dict]:
      # TODO: What is a good location to put this code?
      def convert_csv_string_to_ndarray(row_string):
          """
          Convert a string of comma separated values to a numpy
          float array
          """
          return np.array(
              [np.float32(val) for val in row_string.split(",")]
          )
  
      logger.info("Reading CSV frames")
  
      # TODO: Need to add strong sanity checks on the columns.
  
      # Read the csv in chunks, and only keep the columns we need.
      # Ignore _row_id that we don't need to take care of.
      col_list_names = [
          col.name
          for col in self._column_list
          if col.name != IDENTIFIER_COLUMN
      ]
  
      col_map = {col.name: col for col in self._column_list}
      for chunk in pd.read_csv(
          self.file_url, chunksize=512, usecols=col_list_names
      ):
          # apply the required conversions
          for col in chunk.columns:
              # TODO: Is there a better way to do this?
              if (
                  isinstance(chunk[col].iloc[0], str)
                  and col_map[col].col_object.type.name == "NDARRAY"
              ):
                  # convert the string to a numpy array
                  chunk[col] = chunk[col].apply(
                      convert_csv_string_to_ndarray
                  )
  
          # yield the chunk
          for chunk_index, chunk_row in chunk.iterrows():
              yield chunk_row
  
file_path: evadb/evadb/readers/csv_reader.py
imports: from typing import Dict, Iterator
  import numpy
  import pandas
  from evadb.catalog.sql_config import IDENTIFIER_COLUMN
  from evadb.readers.abstract_reader import AbstractReader
  from evadb.utils.logging_manager import logger
label_desc: Use image node_id 2 for calling the CSVReader obj's underlying member method code with example usage: obj._read() and returns: np