13

I'm trying to do with Python what I the STL function on R.

The R commands are

fit <- stl(elecequip, s.window=5)
plot(fit)

How do I do this in Python? I investigated that statmodels.tsa has some time series analysis functions but I could specifically found "Seasonal Decomposition of Time Series by Loess" in the documentation. Similarly on Python.org there is a library called timeseries 0.5.0, but this doesn't have documentation and it's home site looks down. I know that there is an option with rpy2 using a wrapper, but I don't know how to use the wrapper.

Thanks.

user3724295
  • 193
  • 1
  • 3
  • 12

3 Answers3

18

I've been having a similar issue and am trying to find the best path forward.

Here is a github repo for an STL decomposition based on the Loess procedure. It is based on the original fortran code that was available with this paper. It is really just a python wrapper around the original Fortran code, so you know its likely works well and isn't buggy.

If you want something more Python centric and are willing to go with a slightly simpler decomposition routine, StatsModels has one:

Try moving your data into a Pandas DataFrame and then call StatsModels tsa.seasonal_decompose. See the following example:

import statsmodels.api as sm

dta = sm.datasets.co2.load_pandas().data
# deal with missing values. see issue
dta.co2.interpolate(inplace=True)

res = sm.tsa.seasonal_decompose(dta.co2)
resplot = res.plot()

Three plots produced from above input

You can then recover the individual components of the decomposition from:

res.resid
res.seasonal
res.trend

I hope this helps!

AN6U5
  • 2,755
  • 22
  • 20
  • 2
    Quoting StatsModels 0.6.0 release note: "We added a naive seasonal decomposition tool in the same vein as R’s decompose." So consider that this may not be production-ready. – Guillermo Blasco Feb 09 '15 at 16:08
  • I don't think decompose is as powerful as model based approaches or as the Loess procedure, but it does seem production ready e.g. there aren't reported bugs and it seems to work on the tests I've performed. What else are you seeing that makes you say it isn't production ready? – AN6U5 Feb 10 '15 at 20:22
  • "naive seasonal decomposition" just that, and, well, that means little (naïve bayes, is naive, but works great if the data fits the hypothesis). Also quoting the comments in code "This is a naive decomposition. More sophisticated methods should be preferred." So if it works well for you, great, but keep in mind what you are using. – Guillermo Blasco Feb 12 '15 at 09:17
  • I do link to a seasonal decomposition by Loess procedure, as the OP asked for, which is more sophisticated than Naive Seasonal Decomposition. But since that isn't plug and play ready, I also included the Naive Seasonal Decomposition since it is included in StatsModels. Don't get too caught up in the name of the algorithms and whether or not they include include the word naive as this doesn't reflect its production worthiness, just its versatility and the assumptions that are used in designing the algo. Yes, I do agree that model based methods are more versatile. – AN6U5 Feb 12 '15 at 20:24
  • I want to check the residual and got all of NaNs when using seasonal_decompose, which didn't happen when using R... – LittleLittleQ Jul 11 '17 at 09:32
1

You can also call R from python using rpy2

from rpy2.robjects import r
def decompose(series, frequency, s_window, **kwargs):
    df = pd.DataFrame()
    df['date'] = series.index
    s = [x for x in series.values]
    length = len(series)
    s = r.ts(s, frequency=frequency)
    decomposed = [x for x in r.stl(s, s_window, **kwargs).rx2('time.series')]
    df['observed'] = series.values
    df['trend'] = decomposed[length:2*length]
    df['seasonal'] = decomposed[0:length]
    df['residual'] = decomposed[2*length:3*length]
    return df

The above function assumes that your series has a datetime index. It returns a dataframe with the individual components that you can then graph with your favorite graphing library.

You can pass the parameters for stl seen here, but change any period to underscore, for example the positional argument in the above function is s_window, but in the above link it is s.window. Also, I found some of the above code on this repository.

Jeff Tilton
  • 1,256
  • 1
  • 14
  • 28
0

Another python option is the seasonal package (PyPI, github). It is similar to the StatsModels seasonal_decompose and will also estimate your data's periodicity.

welch
  • 936
  • 8
  • 12