Community Spring Cleaning week is here! Join your fellow Maveryx in digging through your old posts and marking comments on them as solved. Learn more here!

Alteryx Designer Desktop Discussions

Find answers, ask questions, and share expertise about Alteryx Designer Desktop and Intelligence Suite.
SOLVED

Forecasting model in Python unable to write output

danielrg
6 - Meteoroid

Dear Alteryx Community,

 

I am hoping to find here someone who is knowledgeable in both Python and Alteryx.

In order to complete a workflow in Alteryx I require a Croston forecasting model for sporadic demand. I found that this was available in Python so I embedded it in my workflow. I am taking demand over 36 months (attached). I am then attempting to run the following forecasting model:

 

 

# List all non-standard packages to be imported by your 
# script here (only missing packages will be installed)
from ayx import Package
#Package.installPackages(['pandas','numpy'])
import numpy as np
import sys
import random
import matplotlib.pyplot as plt
import pandas as pd

from ayx import Alteryx
ts = Alteryx.read("#1")
def Croston(ts,extra_periods=6,alpha=0.3):

    d = np.array(ts) # Transform the input into a numpy array
    col = len(d) # Historical period length
    d = np.append(d,[np.nan]*extra_periods) # Append np.nan into the demand array to cover future periods
    
    #level (a), periodicity(p) and forecast (f)
    a,p,f = np.full((3,cols+extra_periods),np.nan)
    q = 1 #periods since last demand observation
    
    # Initialization
    first_occurence = np.argmax(d[:cols]>0)
    a[0] = d[first_occurence]
    p[0] = 1 + first_occurence
    f[0] = a[0]/p[0]
# Create all the t+1 forecasts
    for t in range(0,cols):        
        if d[t] > 0:
            a[t+1] = alpha*d[t] + (1-alpha)*a[t] 
            p[t+1] = alpha*q + (1-alpha)*p[t]
            f[t+1] = a[t+1]/p[t+1]
            q = 1           
        else:
            a[t+1] = a[t]
            p[t+1] = p[t]
            f[t+1] = f[t]
            q += 1

    # Future Forecast 
    a[cols+1:cols+extra_periods] = a[cols]
    p[cols+1:cols+extra_periods] = p[cols]
    f[cols+1:cols+extra_periods] = f[cols]
    
    df = pd.DataFrame.from_dict({"Demand":d,"Forecast":f,"Period":p,"Level":a,"Error":d-f})
Alteryx.write(df,1)

 

 

However, the model returns the error that 'df' is not defined:

----------------------
NameError                                 Traceback (most recent call last)
<ipython-input-2-7c889ddf879c> in <module>
     35 
     36     df = pd.DataFrame.from_dict({"Demand":d,"Forecast":f,"Period":p,"Level":a,"Error":d-f})
---> 37 Alteryx.write(df,1)

NameError: name 'df' is not defined

If I indent line 37 I get no output.

 

Any assistance you could offer would be greatly appreciated.

Thank you,

Daniel

5 REPLIES 5
ImadZidan
12 - Quasar

Hello @danielrg ,

 

The python code you have in place is erroneous. I did not look at the logic but rather the structure.

 

You are defining a function and not calling it anywhere.  You need to pay attention to your indentation. It is basically the scope of your code.

 

basically df is out of scope when writing out your output.

 

I have made the code run but not sure about the output required and the logic you desire.

 

Now that it runs, you can debug it and make it fit your needs.

 

I hope you find it helpful.

atcodedog05
22 - Nova
22 - Nova

Hi @danielrg 

 

Among all the major concern is you are not calling function Croston any where.

 

Maybe adding it before write would work.

Croston()
Alteryx.write(df,1)

 

Just looking by the surface level

 

Hope this helps 🙂

 

Its advisable to look into @ImadZidan 's feedback too.

ImadZidan
12 - Quasar

yes @atcodedog05 , you are right.

 

@danielrg , I would start with @atcodedog05  suggestion . you may still get an error as the dimension in your conversion to dataframe is not consistent. 

danielrg
6 - Meteoroid

Thank you both to @ImadZidan and @atcodedog05 . In fact both of you are correct. I combined both of your answers and arrived at the following working function:

 

from ayx import Alteryx

def Croston(ts,extra_periods=6,alpha=0.3):

    d = np.array(ts) # Transform the input into a numpy array
    cols = len(d) # Historical period length
    d = np.append(d,[np.nan]*extra_periods) # Append np.nan into the demand array to cover future periods
    
    #level (a), periodicity(p) and forecast (f)
    a,p,f = np.full((3,cols+extra_periods),np.nan)
    q = 1 #periods since last demand observation
    
    # Initialization
    first_occurence = np.argmax(d[:cols]>0)
    a[0] = d[first_occurence]
    p[0] = 1 + first_occurence
    f[0] = a[0]/p[0]
# Create all the t+1 forecasts
    for t in range(0,cols):        
        if d[t] > 0:
            a[t+1] = alpha*d[t] + (1-alpha)*a[t] 
            p[t+1] = alpha*q + (1-alpha)*p[t]
            f[t+1] = a[t+1]/p[t+1]
            q = 1           
        else:
            a[t+1] = a[t]
            p[t+1] = p[t]
            f[t+1] = f[t]
            q += 1

    # Future Forecast 
    a[cols+1:cols+extra_periods] = a[cols]
    p[cols+1:cols+extra_periods] = p[cols]
    f[cols+1:cols+extra_periods] = f[cols]
    
    df = pd.DataFrame.from_dict({"Demand":a,"Forecast":f,"Period":p})

    return df
Input = Alteryx.read("#1")
Output = Croston(Input)
Alteryx.write(Output,1)

Thank you both very much for looking at it and giving me the insight I needed.

Best,

Daniel 

atcodedog05
22 - Nova
22 - Nova

Happy to help 🙂 @danielrg 

 

Cheers and Happy Analysing 😀

Labels