1

I ran

decompose_result = seasonal_decompose(df["TMAX"],model="additive")
decompose_result.plot();

but the result is

"You must specify a freq or x must be a pandas object with a timeseries index with a freq not set to None"

The data contains only date and tmax (temperature max).

4
  • Most presumably, df["TMAX"] is not 'a pandas object with a timeseries index with a freq not set to None'. Provide some date subset in text.
    – hpchavaz
    Commented Dec 12, 2021 at 13:02
  • date subset?? can you please explain more Commented Dec 12, 2021 at 13:24
  • Sorry, 'data subset'
    – hpchavaz
    Commented Dec 12, 2021 at 16:58
  • Can you provide an excerpt of your dataset? How it looks like df or df['TMAX']?
    – Mario
    Commented Dec 18, 2021 at 13:09

1 Answer 1

2

I assume that you forgot to introduce period and pass it to freq argument for seasonal_decompose() in this line:

decompose_result = seasonal_decompose(df["TMAX"],model="additive")

and it threw out the following ValueError:

---------------------------------------------------------------------------
ValueError                                Traceback (most recent call last)
<ipython-input-2-9b030cf1055e> in <module>()
----> 1 decompose_result = seasonal_decompose(df["TMAX"],model="additive")
      2 decompose_result.plot()

/usr/local/lib/python3.7/dist-packages/statsmodels/tsa/seasonal.py in seasonal_decompose(x, model, filt, freq, two_sided, extrapolate_trend)
    125             freq = pfreq
    126         else:
--> 127             raise ValueError("You must specify a freq or x must be a "
    128                              "pandas object with a timeseries index with "
    129                              "a freq not set to None")

ValueError: You must specify a freq or x must be a pandas object with a time-series index with a freq not set to None

So please follow the below scripts:

# import libraries
import matplotlib.pyplot as plt
import numpy as np
from statsmodels.tsa.seasonal import seasonal_decompose
 
# Generate time-series data
total_duration = 100
step = 0.01
time = np.arange(0, total_duration, step)
 
# Period of the sinusoidal signal in seconds
T= 15
 
# Period component
series_periodic = np.sin((2*np.pi/T)*time)
 
# Add a trend component
k0 = 2
k1 = 2
k2 = 0.05
k3 = 0.001
 
series_periodic = k0*series_periodic
series_trend    = k1*np.ones(len(time))+k2*time+k3*time**2
series          = series_periodic+series_trend 

# Set frequency using period in seasonal_decompose()
period = int(T/step)
results = seasonal_decompose(series, model='additive', freq=period)

trend_estimate    = results.trend
periodic_estimate = results.seasonal
residual          = results.resid
 
# Plot the time-series components
plt.figure(figsize=(14,10))
plt.subplot(221)
plt.plot(series,label='Original time series', color='blue')
plt.legend(loc='best',fontsize=20 , bbox_to_anchor=(0.90, -0.05))
plt.subplot(222)
plt.plot(trend_estimate,label='Trend of time series',color='blue')
plt.legend(loc='best',fontsize=20, bbox_to_anchor=(0.90, -0.05))
plt.subplot(223)
plt.plot(periodic_estimate,label='Seasonality of time series',color='blue')
plt.legend(loc='best',fontsize=20, bbox_to_anchor=(0.90, -0.05))
plt.subplot(224)
plt.plot(residual,label='Decomposition residuals of time series',color='blue')
plt.legend(loc='best',fontsize=20, bbox_to_anchor=(1.09, -0.05))
plt.tight_layout()
plt.savefig('decomposition.png')

Plot the time-series components: img

If you are working with dataframe:

# import libraries
import pandas as pd
import numpy as np
from statsmodels.tsa.seasonal import seasonal_decompose

# Generate some data
np.random.seed(0)
n = 1500

dates = np.array('2020-01-01', dtype=np.datetime64) + np.arange(n)
data = 12*np.sin(2*np.pi*np.arange(n)/365) + np.random.normal(12, 2, 1500)

#=================> Approach#1 <==================
# Set period after building dataframe
df = pd.DataFrame({'TMAX': data}, index=dates)

# Reproduce the OP's example  
seasonal_decompose(df['TMAX'], model='additive', freq=15).plot()

#=================> Approach#2 <==================
# create period once you create pandas dataframe by asfreq() after set dates as index
df = pd.DataFrame({'TMAX': data,}, index=dates).asfreq('D').dropna()

# Reproduce the example for OP
seasonal_decompose(df , model='additive').plot()

img

Not the answer you're looking for? Browse other questions tagged or ask your own question.