问题描述
我需要去掉通量时间序列数据(亮曲线)的趋势,但是当时间序列数据没有简单的线性趋势时,我遇到了一个问题.
我一直在使用scipy.signal.detrend()进行线性案例的趋势消除,但这在这里还不够.
我已经使用numpy.polyfit()尝试多项式去趋势,但是我不确定该如何处理返回的多项式系数.
有人可以建议我采取下一步明智的措施吗?或者,如果有人能够更好地处理非线性数据趋势,那么我也将很高兴听到这个消息.
简而言之,您可以获取polyfit
返回的系数,并将它们传递给polyval
,以在观察到的"x"位置求出多项式. /p>
作为一个独立的示例,假设我们有以下类似内容:
import numpy as np
import matplotlib.pyplot as plt
num = 1000
x = np.linspace(0, 10, num)
y = np.exp(x)
# Add some non-stationary noise that's hard to see without de-trending
noise = 100 * np.exp(0.2 * x) * np.random.normal(0, 1, num)
y += noise
fig, ax = plt.subplots()
ax.plot(x, y, 'ro')
plt.show()
请注意,我在这里没有使用多项式函数来创建y
.那是故意的否则,我们将完全适合并且不需要按照多项式的顺序玩转".
现在让我们尝试使用二阶多项式函数对趋势进行去趋势化(注意在model = np.polyfit(x, y, 2)
行中的2):
import numpy as np
import matplotlib.pyplot as plt
num = 1000
x = np.linspace(0, 10, num)
y = np.exp(x)
# Add some non-stationary noise that's hard to see without de-trending
noise = 100 * np.exp(0.2 * x) * np.random.normal(0, 1, num)
y += noise
# Detrend with a 2d order polynomial
model = np.polyfit(x, y, 2)
predicted = np.polyval(model, x)
fig, axes = plt.subplots(nrows=2, sharex=True)
axes[0].plot(x, y, 'ro')
axes[0].plot(x, predicted, 'k-')
axes[0].set(title='Original Data and 2nd Order Polynomial Trend')
axes[1].plot(x, y - predicted, 'ro')
axes[1].set(title='Detrended Residual')
plt.show()
请注意,我们无法完全拟合数据.这是一个指数函数,我们正在使用多项式.但是,随着我们增加多项式的阶数,我们将更精确地拟合该函数(有开始拟合噪声的风险):
I am needing to detrend flux time series data (light curves), but I'm running into a problem when the time series data doesn't have a simple linear trend.
I've been using scipy.signal.detrend() for the detrending of linear cases, but that isn't sufficient here.
I've used numpy.polyfit() to attempt polynomial detrending, but I'm not sure what to do with the polynomial coefficients it returns.
Can someone advise me as to the next intelligent step to take? Or, if someone has a better method for detrending non-linear data, I'd be delighted to hear that as well.
In a nutshell, you take the coefficients that polyfit
returns and pass them to polyval
to evaluate the polynomial at the observed "x" locations.
As a stand-alone example, let's say we have something similar to the following:
import numpy as np
import matplotlib.pyplot as plt
num = 1000
x = np.linspace(0, 10, num)
y = np.exp(x)
# Add some non-stationary noise that's hard to see without de-trending
noise = 100 * np.exp(0.2 * x) * np.random.normal(0, 1, num)
y += noise
fig, ax = plt.subplots()
ax.plot(x, y, 'ro')
plt.show()
Note that I haven't used a polynomial function here to create y
. That's deliberate. Otherwise, we'd get an exact fit and wouldn't need to "play around" with the order of the polynomial.
Now let's try detrending it with a 2nd order polynomial function (note the 2 in the line model = np.polyfit(x, y, 2)
):
import numpy as np
import matplotlib.pyplot as plt
num = 1000
x = np.linspace(0, 10, num)
y = np.exp(x)
# Add some non-stationary noise that's hard to see without de-trending
noise = 100 * np.exp(0.2 * x) * np.random.normal(0, 1, num)
y += noise
# Detrend with a 2d order polynomial
model = np.polyfit(x, y, 2)
predicted = np.polyval(model, x)
fig, axes = plt.subplots(nrows=2, sharex=True)
axes[0].plot(x, y, 'ro')
axes[0].plot(x, predicted, 'k-')
axes[0].set(title='Original Data and 2nd Order Polynomial Trend')
axes[1].plot(x, y - predicted, 'ro')
axes[1].set(title='Detrended Residual')
plt.show()
Notice that we didn't fit the data exactly. It's an exponential function and we're using a polynomial. However, as we increase the order of the polynomial, we'll fit the function more precisely (at the risk of starting to fit noise):
这篇关于具有非线性趋势的Detrend通量时间序列的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!