class_docstr: The lag based estimator, using lagged observations with aggregation functions
  to forecast the future. This estimator includes the common week-over-week estimation method.
  
  The algorithm support specifying the following:
  
      lag_unit : the unit to calculate lagged values. One of the values in
          `~greykite.sklearn.estimator.lag_based_estimator.LagUnitEnum`.
      lags : a list of lags indicating which lagged ``lag_unit`` data are used in prediction.
          For example, [1, 2] indicating using the past two ``lag_unit`` same time data.
      agg_func : the aggregation function used over the lagged observations.
      agg_func_params : extra parameters used for ``agg_func``.
  
  
  When certain lags are not available, extra data will be extrapolated.
  When predicting into the future and future data is not available,
  predicted values will be used.
  
  Parameters
  ----------
  freq : `str` or None, default None
      The data frequency, used to validate lags.
  lag_unit : `str`, default "week"
      The unit to calculate lagged observations.
      Available options are in `~greykite.sklearn.estimator.lag_based_estimator.LagUnitEnum`.
  lags : `list` [`int`] or None, default None
      The lags in ``lag_unit``'s. [1, 2] indicates using the past two ``lag_unit`` same time values.
      If not provided, the default is to use lag 1 observation only.
  agg_func : `str` or callable, default "mean"
      The aggregation functions used over lagged observations.
  agg_func_params : `dict` or None, default None
      Extra parameters used for ``agg_func``.
  uncertainty_dict: `dict` or None, default None
      How to fit the uncertainty model.
      See `~greykite.sklearn.uncertainty.uncertainty_methods.UncertaintyMethodEnum`.
      If not provided but ``coverage`` is given, this falls back to
      `~greykite.sklearn.uncertainty.simple_conditional_residuals_model.SimpleConditionalResidualsModel`.
  past_df : `pandas.DataFrame` or None, default None
      The past data used to append to the training data.
      If not provided the past data needed will be interpolated.
  series_na_fill_func : `callable` or None, default `lambda s: s.bfill().ffill()`
      The function to fill NAs when they exist.
  
  Attributes
  ----------
  df : `pandas.DataFrame` or None
      The fitted and interpolated training data.
  uncertainty_model : any or None
      The trained uncertainty model.
  max_lag_order : `int` or None
      The maximum lag order.
  min_lag_order : `int` or None
      The minimum lag order.
  train_start : `pandas.Timestamp` or None
      The training start timestamp.
  train_end : `pandas.Timestamp` or None
      The training end timestamp.
class_docstr_tok: ["The","lag","based","estimator",",","using","lagged","observations","with","aggregation","functions","to","forecast","the","future",".","This","estimator","includes","the","common","week-over-week","estimation","method",".","The","algorithm","support","specifying","the","following",":","lag_unit",":","the","unit","to","calculate","lagged","values",".","One","of","the","values","in","`","~greykite.sklearn.estimator.lag_based_estimator.LagUnitEnum","`",".","lags",":","a","list","of","lags","indicating","which","lagged","``","lag_unit","``","data","are","used","in","prediction",".","For","example",",","[","1",",","2","]","indicating","using","the","past","two","``","lag_unit","``","same","time","data",".","agg_func",":","the","aggregation","function","used","over","the","lagged","observations",".","agg_func_params",":","extra","parameters","used","for","``","agg_func","``",".","When","certain","lags","are","not","available",",","extra","data","will","be","extrapolated",".","When","predicting","into","the","future","and","future","data","is","not","available",",","predicted","values","will","be","used",".","Parameters","--","--","--","--","--","freq",":","`","str","`","or","None",",","default","None","The","data","frequency",",","used","to","validate","lags",".","lag_unit",":","`","str","`",",","default","``","week","''","The","unit","to","calculate","lagged","observations",".","Available","options","are","in","`","~greykite.sklearn.estimator.lag_based_estimator.LagUnitEnum","`",".","lags",":","`","list","`","[","`","int","`","]","or","None",",","default","None","The","lags","in","``","lag_unit","``","'s",".","[","1",",","2","]","indicates","using","the","past","two","``","lag_unit","``","same","time","values",".","If","not","provided",",","the","default","is","to","use","lag","1","observation","only",".","agg_func",":","`","str","`","or","callable",",","default","``","mean","''","The","aggregation","functions","used","over","lagged","observations",".","agg_func_params",":","`","dict","`","or","None",",","default","None","Extra","parameters","used","for","``","agg_func","``",".","uncertainty_dict",":","`","dict","`","or","None",",","default","None","How","to","fit","the","uncertainty","model",".","See","`","~greykite.sklearn.uncertainty.uncertainty_methods.UncertaintyMethodEnum","`",".","If","not","provided","but","``","coverage","``","is","given",",","this","falls","back","to","`","~greykite.sklearn.uncertainty.simple_conditional_residuals_model.SimpleConditionalResidualsModel","`",".","past_df",":","`","pandas.DataFrame","`","or","None",",","default","None","The","past","data","used","to","append","to","the","training","data",".","If","not","provided","the","past","data","needed","will","be","interpolated",".","series_na_fill_func",":","`","callable","`","or","None",",","default","`","lambda","s",":","s.bfill","(",")",".ffill","(",")","`","The","function","to","fill","NAs","when","they","exist",".","Attributes","--","--","--","--","--","df",":","`","pandas.DataFrame","`","or","None","The","fitted","and","interpolated","training","data",".","uncertainty_model",":","any","or","None","The","trained","uncertainty","model",".","max_lag_order",":","`","int","`","or","None","The","maximum","lag","order",".","min_lag_order",":","`","int","`","or","None","The","minimum","lag","order",".","train_start",":","`","pandas.Timestamp","`","or","None","The","training","start","timestamp",".","train_end",":","`","pandas.Timestamp","`","or","None","The","training","end","timestamp","."]
docstr: Processes the training data. Including appending ``past_df``, interpolation, etc.
  
  Returns
  -------
  This function modifies class instance attributes and does not return anything.
docstr_tok: ["Processes","the","training","data",".","Including","appending","``","past_df","``",",","interpolation",",","etc",".","Returns","--","--","--","-","This","function","modifies","class","instance","attributes","and","does","not","return","anything","."]
code: def _prepare_df(self):
      """Processes the training data. Including appending ``past_df``, interpolation, etc.
  
      Returns
      -------
      This function modifies class instance attributes and does not return anything.
      """
      self.df[self.time_col_] = pd.to_datetime(self.df[self.time_col_])
      self.df = self.df.sort_values(by=self.time_col_).reset_index(
          drop=True
      )
      # Infers data frequency.
      freq = infer_freq(self.df, self.time_col_)
      if self.freq is None:
          self.freq = freq
      if freq is not None and self.freq != freq:
          log_message(
              message=f"The inferred frequency '{freq}' is different from the provided '{self.freq}'. "
              f"Using the provided frequency.",
              level=LoggingLevelEnum.INFO,
          )
      if self.freq is None:
          raise ValueError(
              "Frequency can not be inferred. Please provide frequency."
          )
      # Currently "M" frequency is not handled well with `dateutil.relativedelta`.
      # For example, 2020-02-29 minus 1 month is 2020-01-29 instead of 2020-01-31,
      # which does not match the last data point.
      # Since this is not a typical use case, we will fix it later and raise a warning for now.
      # "MS" is preferred.
      if self.freq == "M":
          log_message(
              message="The data frequency is 'M' which may lead to unexpected behaviors. "
              "Please convert to 'MS' if applicable.",
              level=LoggingLevelEnum.WARNING,
          )
      # Checks ``self.lag_unit`` is at least ``self.freq``.
      example_ts = pd.date_range(
          start=self.df[self.time_col_].min(), freq=self.freq, periods=2
      )  # makes a ts with data frequency
      if example_ts[0] + self.lag_unit_delta < example_ts[1]:
          raise ValueError(
              f"The lag unit '{self.lag_unit}' must be at least equal to the data frequency '{self.freq}'."
          )
      # Gets the earliest timestamp needed.
      self.train_start = self.df[self.time_col_].iloc[0]
      self.train_end = self.df[self.time_col_].iloc[-1]
      earliest_timestamp = (
          self.train_start - self.lag_unit_delta * self.max_lag_order
      )
      df_earliest_timestamp = pd.DataFrame(
          {
              self.time_col_: [earliest_timestamp],
              self.value_col_: [np.nan],
          }
      )
      # Gets all timestamps needed.
      self.df = fill_missing_dates(
          df=pd.concat(
              [df_earliest_timestamp, self.df], axis=0
          ).reset_index(drop=True),
          time_col=self.time_col_,
          freq=self.freq,
      )[0]
      # Takes values from ``past_df`` if exist.
      if self.past_df is not None and len(self.past_df) > 0:
          self.past_df[self.time_col_] = pd.to_datetime(
              self.past_df[self.time_col_]
          )
          self.past_df = self.past_df.sort_values(
              by=self.time_col_
          ).reset_index(drop=True)
          merge_df = self.df.merge(
              self.past_df[[self.time_col_, self.value_col_]].rename(
                  columns={self.value_col_: f"{self.value_col_}_p"}
              ),
              on=self.time_col_,
              how="left",
          )
          self.df[self.value_col_] = merge_df[
              self.value_col_
          ].combine_first(merge_df[f"{self.value_col_}_p"])
      # Fills missing values.
      if self.series_na_fill_func is not None:
          self.df[self.value_col_] = self.series_na_fill_func(
              self.df[self.value_col_]
          )
  
imports: from enum import Enum
  from typing import List
  from typing import Optional
  from typing import Union
  import numpy
  import pandas
  from dateutil.relativedelta import relativedelta
  from sklearn.metrics import mean_squared_error
  from greykite.common import constants
  from greykite.common.aggregation_function_enum import AggregationFunctionEnum
  from greykite.common.logging import LoggingLevelEnum
  from greykite.common.logging import log_message
  from greykite.common.time_properties import fill_missing_dates
  from greykite.common.time_properties import infer_freq
  from greykite.sklearn.estimator.base_forecast_estimator import BaseForecastEstimator
label_desc: Use image node_id 5 for calling the LagBasedEstimator obj's underlying member method code with example usage: obj._prepare_df() without return types