Python 如何检测时间序列中的翻转?
对于在不同操作模式下运行的系统,我希望减少模式之间的翻转。为此,需要检测翻转并进行校正 假设我们有一个模式频繁切换的序列:Python 如何检测时间序列中的翻转?,python,time-series,Python,Time Series,对于在不同操作模式下运行的系统,我希望减少模式之间的翻转。为此,需要检测翻转并进行校正 假设我们有一个模式频繁切换的序列: before = [0,0,0,(1,0),1,1,1,2,2,(1,2),1,1,1,(0,1),0] # parenthesis indicate flipping 我只想在(变化点)进行某种交换,以获得: 如何实现这一点?我通过开发一个用于翻转检测的小型卷积滤波器解决了这个问题。 到目前为止,它可以检测到单个翻转(开-关-开或关-开-关) 构建差分信号允许支持不
before = [0,0,0,(1,0),1,1,1,2,2,(1,2),1,1,1,(0,1),0] # parenthesis indicate flipping
我只想在(变化点)进行某种交换,以获得:
如何实现这一点?我通过开发一个用于翻转检测的小型卷积滤波器解决了这个问题。 到目前为止,它可以检测到单个翻转(开-关-开或关-开-关) 构建差分信号允许支持不同的单交换,即使在两种以上的操作模式之间也是如此
import numpy as np
import matplotlib.pyplot as plt
before = np.array([0,0,1,0,0,1,0,1,1,1,2,2,1,2,1,1,1,0,1,0,0])
goal = np.array( [0,0,0,0,0,0,1,1,1,1,2,2,2,1,1,1,1,1,0,0,0])
after = before.copy()
fltr = np.array([1,2,5,10]) # convolution filter
for i in range(0,len(before)-4):
dif = np.diff(after)
conv = (fltr*dif[i:i+4]).sum() # conv-filter applied on diff()
if abs(conv) == 3: # 00100 = 00000 or 11011 = 11111
after[i+2] = after[i+1]
if abs(conv) == 7:
b = after[i+2] # 00101 = 00011 or 11010 = 11100
after[i+2] = after[i+3]
after[i+3] = b
plt.plot(before, linestyle='--',label='before')
plt.plot(goal, linestyle='-.',label='goal')
plt.plot(after, linestyle=':', label='after')
plt.legend()
plt.show
注意:此解决方案可能不完整,无法涵盖所有可能的场景。请推荐更高级/替代解决方案。有一种“更简单”的方法来查找范围1的翻转,但不适用于连续重复翻转
before = np.array([0,0,1,0,0,1,0,1,1,1,2,2,1,2,1,1,1,0,1,0,0])
goal = np.array( [0,0,0,0,0,0,1,1,1,1,2,2,2,1,1,1,1,1,0,0,0])
diff = np.diff(before) # find 'jumps' with range 1
diff[:-1][(diff == 0)[1:]] = 0 # correct 'right' side of 'jumps'
after = before - np.r_[0,diff] # correct flipping
plt.plot(before, linestyle='--',label='before')
plt.plot(goal, linestyle='-.',label='goal')
plt.plot(after, linestyle=':', label='after')
plt.legend();
输出
使用更大的步幅和负“跳跃”
before = np.array([0,0,-1,0,0,1,0,1,1,1,4,4,1,4,1,1,1,0,1,0,0])
goal = np.array( [0,0, 0,0,0,0,1,1,1,1,4,4,4,1,1,1,1,1,0,0,0])
diff = np.diff(before) # find flipping with range 1
diff[:-1][(diff == 0)[1:]] = 0 # correct 'right' side of signal
after = before - np.r_[0,diff] # correct flipping
plt.plot(before, linestyle='--',label='before')
plt.plot(goal, linestyle='-.',label='goal')
plt.plot(after, linestyle=':', label='after')
plt.legend();
输出
解的极限
- 连续反复翻转
你的问题很有趣。我认为你自己的努力应该是问题的一部分。起初我认为这个问题已经得到了恰当的回答。像
0,1,2
或0,1,1,2
这样的模式变化是否可能?甚至0,2
?事实上,答案反映了我自己的解决方案,因为到目前为止我还没有得到外部支持。我最初的问题在三天后就结束了。@Wups到目前为止,它只考虑了单个步骤。使用卷积方法,通过添加额外的if语句,可以轻松添加两个步骤。重要的是确保没有引入歧义。这就是为什么我的过滤器值被选择为[1,2,5,10]
。您能解释一下为什么要使用过滤器吗?您可以将每个样本与下一个(和上一个)样本进行比较以查看翻转情况?使用卷积过滤器的优点是,它不仅考虑当前和上一个样本。当卷积集成超过5个样本(4个差异)时,它将2个样本展望未来和过去。如果你用If语句实现它,它会变得非常混乱。这是一个非常好的观点。当系统不断翻转时,不能将其分配到一个或另一个状态。但是您仍然可以使用卷积来检测它[0,1,0,1,0]将卷积为-6,“[1,0,1,0,1]将根据我下面的答案给出6。”
before = np.array([0,0,-1,0,0,1,0,1,1,1,4,4,1,4,1,1,1,0,1,0,0])
goal = np.array( [0,0, 0,0,0,0,1,1,1,1,4,4,4,1,1,1,1,1,0,0,0])
diff = np.diff(before) # find flipping with range 1
diff[:-1][(diff == 0)[1:]] = 0 # correct 'right' side of signal
after = before - np.r_[0,diff] # correct flipping
plt.plot(before, linestyle='--',label='before')
plt.plot(goal, linestyle='-.',label='goal')
plt.plot(after, linestyle=':', label='after')
plt.legend();
before = [0,1,0,1,0,1,1,1,1]
goal = [0,0,0,0,1,1,1,1,1]