class_docstr: An abstract pipeline loader for estimates data that can load data a
  variable number of quarters forwards/backwards from calendar dates
  depending on the `num_announcements` attribute of the columns' dataset.
  If split adjustments are to be applied, a loader, split-adjusted columns,
  and the split-adjusted asof-date must be supplied.
  
  Parameters
  ----------
  estimates : pd.DataFrame
      The raw estimates data.
      ``estimates`` must contain at least 5 columns:
          sid : int64
              The asset id associated with each estimate.
  
          event_date : datetime64[ns]
              The date on which the event that the estimate is for will/has
              occurred..
  
          timestamp : datetime64[ns]
              The date on which we learned about the estimate.
  
          fiscal_quarter : int64
              The quarter during which the event has/will occur.
  
          fiscal_year : int64
              The year during which the event has/will occur.
  
  name_map : dict[str -> str]
      A map of names of BoundColumns that this loader will load to the
      names of the corresponding columns in `events`.
class_docstr_tok: ["An","abstract","pipeline","loader","for","estimates","data","that","can","load","data","a","variable","number","of","quarters","forwards\/backwards","from","calendar","dates","depending","on","the","`","num_announcements","`","attribute","of","the","columns","'","dataset",".","If","split","adjustments","are","to","be","applied",",","a","loader",",","split-adjusted","columns",",","and","the","split-adjusted","asof-date","must","be","supplied",".","Parameters","--","--","--","--","--","estimates",":","pd.DataFrame","The","raw","estimates","data",".","``","estimates","``","must","contain","at","least","5","columns",":","sid",":","int64","The","asset","id","associated","with","each","estimate",".","event_date",":","datetime64","[","ns","]","The","date","on","which","the","event","that","the","estimate","is","for","will\/has","occurred","..","timestamp",":","datetime64","[","ns","]","The","date","on","which","we","learned","about","the","estimate",".","fiscal_quarter",":","int64","The","quarter","during","which","the","event","has\/will","occur",".","fiscal_year",":","int64","The","year","during","which","the","event","has\/will","occur",".","name_map",":","dict","[","str","-",">","str","]","A","map","of","names","of","BoundColumns","that","this","loader","will","load","to","the","names","of","the","corresponding","columns","in","`","events","`","."]
code: def load_adjusted_array(self, columns, dates, assets, mask):
      # Separate out getting the columns' datasets and the datasets'
      # num_announcements attributes to ensure that we're catching the right
      # AttributeError.
      col_to_datasets = {col: col.dataset for col in columns}
      try:
          groups = groupby(
              lambda col: col_to_datasets[col].num_announcements,
              col_to_datasets,
          )
      except AttributeError:
          raise AttributeError(
              "Datasets loaded via the "
              "EarningsEstimatesLoader must define a "
              "`num_announcements` attribute that defines "
              "how many quarters out the loader should load"
              " the data relative to `dates`."
          )
      if any(num_qtr < 0 for num_qtr in groups):
          raise ValueError(
              INVALID_NUM_QTRS_MESSAGE
              % ",".join(str(qtr) for qtr in groups if qtr < 0)
          )
      out = {}
      # To optimize performance, only work below on assets that are
      # actually in the raw data.
      assets_with_data = set(assets) & set(
          self.estimates[SID_FIELD_NAME]
      )
      last_per_qtr, stacked_last_per_qtr = self.get_last_data_per_qtr(
          assets_with_data, columns, dates
      )
      # Determine which quarter is immediately next/previous for each
      # date.
      zeroth_quarter_idx = self.get_zeroth_quarter_idx(
          stacked_last_per_qtr
      )
      zero_qtr_data = stacked_last_per_qtr.loc[zeroth_quarter_idx]
  
      for num_announcements, columns in groups.items():
          requested_qtr_data = self.get_requested_quarter_data(
              zero_qtr_data,
              zeroth_quarter_idx,
              stacked_last_per_qtr,
              num_announcements,
              dates,
          )
  
          # Calculate all adjustments for the given quarter and accumulate
          # them for each column.
          col_to_adjustments = self.get_adjustments(
              zero_qtr_data,
              requested_qtr_data,
              last_per_qtr,
              dates,
              assets,
              columns,
          )
  
          # Lookup the asset indexer once, this is so we can reindex
          # the assets returned into the assets requested for each column.
          # This depends on the fact that our column multiindex has the same
          # sids for each field. This allows us to do the lookup once on
          # level 1 instead of doing the lookup each time per value in
          # level 0.
          asset_indexer = assets.get_indexer_for(
              requested_qtr_data.columns.levels[1],
          )
          for col in columns:
              column_name = self.name_map[col.name]
              # allocate the empty output with the correct missing value
              output_array = np.full(
                  (len(dates), len(assets)),
                  col.missing_value,
                  dtype=col.dtype,
              )
              # overwrite the missing value with values from the computed
              # data
              output_array[
                  :,
                  asset_indexer,
              ] = requested_qtr_data[column_name].values
              out[col] = AdjustedArray(
                  output_array,
                  mask,
                  # There may not be any adjustments at all (e.g. if
                  # len(date) == 1), so provide a default.
                  dict(col_to_adjustments.get(column_name, {})),
                  col.missing_value,
              )
      return out
  
imports: from abc import abstractmethod, abstractproperty
  import numpy
  import pandas
  from six import viewvalues
  from toolz import groupby
  from catalyst.lib.adjusted_array import AdjustedArray
  from catalyst.lib.adjustment import Datetime641DArrayOverwrite, Datetime64Overwrite, Float641DArrayOverwrite, Float64Multiply, Float64Overwrite
  from catalyst.pipeline.common import EVENT_DATE_FIELD_NAME, FISCAL_QUARTER_FIELD_NAME, FISCAL_YEAR_FIELD_NAME, SID_FIELD_NAME, TS_FIELD_NAME
  from catalyst.pipeline.loaders.base import PipelineLoader
  from catalyst.utils.numpy_utils import datetime64ns_dtype, float64_dtype
  from catalyst.pipeline.loaders.utils import ffill_across_cols, last_in_date_group
label_desc: Use image node_id 14 for calling the EarningsEstimatesLoader obj's underlying member method code with example usage: obj.load_adjusted_array(columns, dates, assets, mask) and returns: out