I wanted to reveal hard to see correlation in data via computing the ratio of the standard deviation to the mean over the given bandwidth. The window would be shifted one frequency bin to the right, and the ratio is computed again, and so on. I thought it is possible with ready function from Matplotlib or scipy library? I would be very grateful for showing me the solution.
Asked
Active
Viewed 2,261 times
2
-
As a word of advice, it will be easier for people to answer your questions if you include some dummy data, such as you create time series data: ```python import pandas as pd import numpy as np ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000)).cumsum() ``` – CypherX Sep 10 '19 at 00:36
1 Answers
3
Solution
What you are trying to calculate is a rolling version of Relative Standard Deviation (RSD), which is also known as Coefficient of Variation (CV). See Wikipedia and Investopedia for more details on the definition.
RSD = CV = SD/Mean
Let us make some time-series data first.
import pandas as pd
import numpy as np
# some sample data
ts = pd.Series(np.random.randn(1000),
index=pd.date_range('1/1/2000',
periods=1000)).cumsum()
The following piece of code will give you what you need.
Option-A
window = 60
rolling_rsd = ts.rolling(window=window).std()/ts.rolling(window=window).mean()
Option-B
Or, you could use this convenience function:
def rsd(ts, window = 60):
"""
Returns the Relative Standard Deviation (RSD),
a.k.a Coefficient of Variation (CV) for a
given rolling window size on a time series data-column.
ts = time series data
window = window size to compute rolling mean, std, rsd
Example:
rolling_rsd, rolling_mean, rolling_std = rsd(ts, window = 60)
"""
rolling_mean = ts.rolling(window=window).mean()
rolling_std = ts.rolling(window=window).std()
rolling_rsd = rolling_std/rolling_mean
return (rolling_rsd, rolling_mean, rolling_std)
Detailed Example
I will use convenience function, rsd()
for following example.
import pandas as pd
import numpy as np
# some sample data
ts = pd.Series(np.random.randn(1000), index=pd.date_range('1/1/2000', periods=1000)).cumsum()
#plot the time series
ts.plot(style='k--')
# Using convenience function: rsd()
# calculate rolling RSD, MEAN and STD with window = 60
(rolling_rsd, rolling_mean, rolling_std) = rsd(ts, window = 60)
# calculate a 60 day rolling mean and plot
rolling_mean.plot(style='k')
# add the 60 day rolling standard deviation (STD) to the plot
rolling_std.plot(style='b')
# add the 60 day rolling relative standard deviation (RSD) to the plot
rolling_rsd.plot(style='r')
Note:
You could also just calculate this directly as follows (if you prefer not to use another function).
# calculate a 60 day rolling standard deviation (rsd)
rolling_rsd = ts.rolling(window=60).std()/ts.rolling(window=60).mean()
Related Solution/Question:

CypherX
- 7,019
- 3
- 25
- 37
-
How to do the rolling with data "ts"? My command to create "ts" is `ts = data.fft()`. – Paweł Chmolewski Sep 10 '19 at 22:33
-
@PawełChmolewski: look for pandas.Series with numpy array. `ts = pd.Series(data.fft())`. [Source](https://www.w3resource.com/python-exercises/pandas/python-pandas-data-series-exercise-6.php) – CypherX Sep 10 '19 at 22:33
-
-
@PawełChmolewski Thank you for choosing the response as the **`accepted`** solution. Could you please also **`upvote`** this solution? – CypherX Sep 12 '19 at 01:55