(self)
Execute the forecast algorithm according to the request type
Execute the forecast algorithm according to the request type
Execute the forecast algorithm according to the request type
def _forecast(self):
        """
        Execute the forecast algorithm according to the request type
        """
        
        # If this is a seasonality request, we need to return the relevant seasonlity component
        if self.is_seasonality_request:

            if self.seasonality == 'weekly':
                # Prepare the seasonality data frame
                # Parameter start needs to be any arbitrary week starting on a Sunday
                days = (pd.date_range(start='2017-01-01', periods=7) + pd.Timedelta(days=self.weekly_start))
                df_w = plot.seasonality_plot_df(self.model, days)

                # Calculate seasonal components 
                self.forecast = self.model.predict_seasonal_components(df_w)

            elif self.seasonality == 'yearly':
                # Prepare the seasonality data frame
                # Parameter start needs to be 1st January for any arbitrary year
                days = (pd.date_range(start='2017-01-01', periods=365) + pd.Timedelta(days=self.yearly_start))
                df_y = plot.seasonality_plot_df(self.model, days)

                # Calculate seasonal components 
                self.forecast = self.model.predict_seasonal_components(df_y)

            else:
                # Prepare the seasonality data frame
                start = pd.to_datetime('2017-01-01 0000')
                period = self.model.seasonalities[self.seasonality]['period']
                
                end = start + pd.Timedelta(days=period)
                # plot_points = 200
                # plot_points is used instead of period below in fbprophet/forecaster.py. 
                # However, it seems to make more sense to use period given the expected usage in Qlik
                intervals = pd.to_datetime(np.linspace(start.value, end.value, period)) 
                
                df_x = plot.seasonality_plot_df(self.model, intervals)

                # Calculate seasonal components 
                self.forecast = self.model.predict_seasonal_components(df_x)
            
            # Set the correct sort order for the response
            try:
                self.forecast = self.forecast.reindex(self.sort_order.index)
            except AttributeError:
                pass
        
        # For standard forecast the output rows equal the input rows
        else:
            # Prepare the forecast
            self.forecast = self.model.predict(self.future_df)
            
            # For return=y_then_yhat[_upper / _lower] we return y values followed by relevant results for the forecast periods
            if 'y_then_yhat' in self.result_type:
                relevant_result = self.result_type.replace('y_then_', '')

                # Copy yhat / yhat_upper / yhat_lower values to the new column
                self.forecast.loc[:, self.result_type] = self.forecast.loc[:, relevant_result]

                if 'upper' in self.result_type or 'lower' in self.result_type:
                    # Overwrite historic values with Nulls
                    self.forecast.loc[:len(self.forecast) - self.periods - 1, self.result_type] \
                    = np.NaN
                else:
                    # Overwrite with y values for historic data
                    self.forecast.loc[:len(self.forecast) - self.periods - 1, self.result_type] \
                    = self.input_df.loc[:len(self.request_df) - self.periods - 1, 'y']
            
            # For return=residual we return y - yhat for historical periods and Null for future periods
            elif 'residual' in self.result_type:
                # Create the residuals for historical periods by subtracting yhat from y
                self.forecast.loc[:len(self.request_df)-self.periods-1, self.result_type] = self.input_df.loc[:len(self.request_df)-self.periods-1, 'y'] - self.forecast.loc[:len(self.request_df)-self.periods-1, 'yhat']
            
            # Update to the original index from the request data frame
            self.forecast.index = self.request_index.index
            
            # Reset to the original sort order of the data sent by Qlik
            self.forecast = self.forecast.sort_index()

        # Undo the logarithmic conversion if it was applied during initialization
        if self.take_log:
            if self.result_type == 'all':
                self.forecast.loc[:, self.forecast.columns != 'ds'] = np.exp(self.forecast.loc[:, self.forecast.columns != 'ds'])
            else:
                self.forecast.loc[:, self.result_type] = np.exp(self.forecast.loc[:, self.result_type])

        # Add back the null row if it was received in the request
        if len(self.NaT_df) > 0:
            if self.result_type == 'all':
                col = 'yhat'
            else:
                col = self.result_type
            self.NaT_df = self.NaT_df.rename({'y': col}, axis='columns')
            self.forecast = self.forecast.append(self.NaT_df)
def _forecast ( self ) : # If this is a seasonality request, we need to return the relevant seasonlity component if self . is_seasonality_request : if self . seasonality == 'weekly' : # Prepare the seasonality data frame # Parameter start needs to be any arbitrary week starting on a Sunday days = ( pd . date_range ( start = '2017-01-01' , periods = 7 ) + pd . Timedelta ( days = self . weekly_start ) ) df_w = plot . seasonality_plot_df ( self . model , days ) # Calculate seasonal components  self . forecast = self . model . predict_seasonal_components ( df_w ) elif self . seasonality == 'yearly' : # Prepare the seasonality data frame # Parameter start needs to be 1st January for any arbitrary year days = ( pd . date_range ( start = '2017-01-01' , periods = 365 ) + pd . Timedelta ( days = self . yearly_start ) ) df_y = plot . seasonality_plot_df ( self . model , days ) # Calculate seasonal components  self . forecast = self . model . predict_seasonal_components ( df_y ) else : # Prepare the seasonality data frame start = pd . to_datetime ( '2017-01-01 0000' ) period = self . model . seasonalities [ self . seasonality ] [ 'period' ] end = start + pd . Timedelta ( days = period ) # plot_points = 200 # plot_points is used instead of period below in fbprophet/forecaster.py.  # However, it seems to make more sense to use period given the expected usage in Qlik intervals = pd . to_datetime ( np . linspace ( start . value , end . value , period ) ) df_x = plot . seasonality_plot_df ( self . model , intervals ) # Calculate seasonal components  self . forecast = self . model . predict_seasonal_components ( df_x ) # Set the correct sort order for the response try : self . forecast = self . forecast . reindex ( self . sort_order . index ) except AttributeError : pass # For standard forecast the output rows equal the input rows else : # Prepare the forecast self . forecast = self . model . predict ( self . future_df ) # For return=y_then_yhat[_upper / _lower] we return y values followed by relevant results for the forecast periods if 'y_then_yhat' in self . result_type : relevant_result = self . result_type . replace ( 'y_then_' , '' ) # Copy yhat / yhat_upper / yhat_lower values to the new column self . forecast . loc [ : , self . result_type ] = self . forecast . loc [ : , relevant_result ] if 'upper' in self . result_type or 'lower' in self . result_type : # Overwrite historic values with Nulls self . forecast . loc [ : len ( self . forecast ) - self . periods - 1 , self . result_type ] = np . NaN else : # Overwrite with y values for historic data self . forecast . loc [ : len ( self . forecast ) - self . periods - 1 , self . result_type ] = self . input_df . loc [ : len ( self . request_df ) - self . periods - 1 , 'y' ] # For return=residual we return y - yhat for historical periods and Null for future periods elif 'residual' in self . result_type : # Create the residuals for historical periods by subtracting yhat from y self . forecast . loc [ : len ( self . request_df ) - self . periods - 1 , self . result_type ] = self . input_df . loc [ : len ( self . request_df ) - self . periods - 1 , 'y' ] - self . forecast . loc [ : len ( self . request_df ) - self . periods - 1 , 'yhat' ] # Update to the original index from the request data frame self . forecast . index = self . request_index . index # Reset to the original sort order of the data sent by Qlik self . forecast = self . forecast . sort_index ( ) # Undo the logarithmic conversion if it was applied during initialization if self . take_log : if self . result_type == 'all' : self . forecast . loc [ : , self . forecast . columns != 'ds' ] = np . exp ( self . forecast . loc [ : , self . forecast . columns != 'ds' ] ) else : self . forecast . loc [ : , self . result_type ] = np . exp ( self . forecast . loc [ : , self . result_type ] ) # Add back the null row if it was received in the request if len ( self . NaT_df ) > 0 : if self . result_type == 'all' : col = 'yhat' else : col = self . result_type self . NaT_df = self . NaT_df . rename ( { 'y' : col } , axis = 'columns' ) self . forecast = self . forecast . append ( self . NaT_df )