code: def fetch(self, columns: Iterable[str]) -> pa.Table:
      projected = self._df[columns].copy(deep=False)
  
      for col, pd_type in projected.dtypes.items():
          # Handle cases that need to happen before conversion to pyarrow
          if col in self._casts:
              projected[col] = projected[col].astype(self._casts[col])
  
          # Handle expanding categoricals
          if isinstance(pd_type, pd.CategoricalDtype):
              cat = projected[col].cat
              projected[col] = cat.categories[cat.codes]
  
      table = pa.Table.from_pandas(projected, preserve_index=False)
  
      # Split into batches of desired size
      if self._batch_size is None:
          return table
      else:
          # Resize batches
          batches = table.to_batches(self._batch_size)
          return pa.Table.from_batches(batches, table.schema)
  
file_path: vegafusion/python/vegafusion/vegafusion/datasource/pandas_datasource.py
imports: from typing import Iterable
  from math import floor
  import pandas
  import pyarrow
  from .datasource import Datasource
label_desc: Use image node_id 3 for calling the PandasDatasource obj's underlying member method code with example usage: obj.fetch(columns) and returns: table, pa