code: def ffill_across_cols(df, columns, name_map):
      """
      Forward fill values in a DataFrame with special logic to handle cases
      that pd.DataFrame.ffill cannot and cast columns to appropriate types.
  
      Parameters
      ----------
      df : pd.DataFrame
          The DataFrame to do forward-filling on.
      columns : list of BoundColumn
          The BoundColumns that correspond to columns in the DataFrame to which
          special filling and/or casting logic should be applied.
      name_map: map of string -> string
          Mapping from the name of each BoundColumn to the associated column
          name in `df`.
      """
      df.ffill(inplace=True)
  
      # Fill in missing values specified by each column. This is made
      # significantly more complex by the fact that we need to work around
      # two pandas issues:
  
      # 1) When we have sids, if there are no records for a given sid for any
      #    dates, pandas will generate a column full of NaNs for that sid.
      #    This means that some of the columns in `dense_output` are now
      #    float instead of the intended dtype, so we have to coerce back to
      #    our expected type and convert NaNs into the desired missing value.
  
      # 2) DataFrame.ffill assumes that receiving None as a fill-value means
      #    that no value was passed.  Consequently, there's no way to tell
      #    pandas to replace NaNs in an object column with None using fillna,
      #    so we have to roll our own instead using df.where.
      for column in columns:
          column_name = name_map[column.name]
          # Special logic for strings since `fillna` doesn't work if the
          # missing value is `None`.
          if column.dtype == categorical_dtype:
              df[column_name] = df[column.name].where(
                  pd.notnull(df[column_name]), column.missing_value
              )
          else:
              # We need to execute `fillna` before `astype` in case the
              # column contains NaNs and needs to be cast to bool or int.
              # This is so that the NaNs are replaced first, since pandas
              # can't convert NaNs for those types.
              df[column_name] = (
                  df[column_name]
                  .fillna(column.missing_value)
                  .astype(column.dtype)
              )
  
file_path: zipline/zipline/pipeline/loaders/utils.py
imports: import numpy
  import pandas
  from zipline.errors import NoFurtherDataError
  from zipline.pipeline.common import TS_FIELD_NAME, SID_FIELD_NAME
  from zipline.utils.numpy_utils import categorical_dtype
label_desc: Use image node_id 6 for calling a global function with example usage: ffill_across_cols(df, columns, name_map) without return types