微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

查找信号斜率上的所有点

如何解决查找信号斜率上的所有点

我有一个 1d 信号,如下所示

x = np.array([34.69936612,34.70083619,37.38802174,39.67141565,49.05662135,63.87593075,67.70815746,72.06562117,79.31063707,85.13125285,83.34185985,72.74589905,57.34778159,58.63283664,64.92526896,65.89153823,66.07273386,59.68722257,59.6801125,59.41456929,58.19250575,59.92192524,58.42078866,55.45131784,55.09849914,54.95270916,49.60804717,43.05198366,36.10104167,26.88848229,25.38550393,28.71305461,30.03802157,31.3520023,32.59509437,32.67600055,32.68801666,32.61500098,32.65303828,32.72752018,32.84099458,31.46154937,32.70809456,27.67842221,25.65302641,30.08500957,31.41003082,32.91935844,32.92452782,35.56587345,30.09272452,35.60898454,49.12005244,85.79396522,71.81950127,63.91915245,69.14879246,70.43600086,71.71703424,71.74830965,70.51400086,70.50201501,70.50202228,67.91157904,66.62396413,67.90736076,66.5410636,67.96748026,67.94177515,65.30929726,65.29901863,66.60282538,66.60666811,66.55100589,65.33825435,66.55222626,65.29656691,66.56003543,65.30964145,64.07556963,63.99339626,62.86668124,60.43549001,61.68116229,61.61140279,62.65181523,62.70844205,62.77783077,64.03882299,65.39701193,65.40123835,65.41845477,65.42941287,65.38851043,65.36201151,73.33102635,73.84443755,70.94806114,68.18793023,69.20003749,66.61045573,65.38106858,64.05484531,63.88684974,62.64420529,62.69196131,62.74418993,62.72175294,64.01210311,64.1590297,63.0284751,64.27265024,64.24984689,62.90213438,62.68704697,62.65233151,63.09040365,63.10330994,62.72787413,63.95427977,63.89707325,61.38203635,57.48587612,60.05764178,62.70293674,61.38484666,60.07995823,61.34569129,62.66307354,61.38549663,61.34835356,61.3888718,61.48381576,62.74226583,62.83945058,41.78731982,38.06452548,40.57553545,43.10410628,43.17965777,44.41576623,45.67422069,44.44681128,44.52855717,45.69118569,45.7559632,49.9019806,50.90898633,52.2603325,36.83061979,48.36714502,53.60110239,53.58750501,51.03745637,52.15201941,50.94600264,48.50758345,51.03154956,51.32249134,51.49705585,53.46467209,51.708078,48.1404585,46.32157084,53.20416229,60.52216104,67.14976382,66.6844348,63.99400013,63.89292312,63.94972283,65.33551293,66.54723199,65.29004129,67.87224117,69.3810433,69.28915977,65.32064534,64.07644938,64.59988251,65.55365125,64.3440046,64.4526091,63.38977665,64.61810574,63.52989024,63.55126155,64.4263114,64.43874937,64.78594756,66.03974204,67.34958445,70.07248445,67.40968741,66.56554542,67.59965865,67.85658168,67.62022101,67.87089721,61.22552792,54.07823817,47.96332512,53.22944931,54.77573267,59.55033053,62.24247612,62.24529416,63.9429676,63.13145527,63.29764489,63.2723988,62.96359318,63.3025575,63.47790181,63.29642863,63.50702402,63.71413853,63.71470992,62.25079434,63.46787461,63.73497156,63.77631175,63.69024723,63.55254533,63.97794376,64.05815662,63.57687055,66.80917018,66.82863683,66.27964922,65.04852024,65.29135318,65.57783886,65.52090561,65.29656225,65.32543578,66.52825603,67.1314033,50.03567181,53.53803024,53.56862071,55.10515723,55.14010716,63.30760687,62.7114906,62.95237442,62.75869066,64.19585539,62.70371169,62.65204241,62.69394807,62.94844878,58.36397143,59.68285611,60.89452752,60.97356663,60.72068974,59.62036073,60.52789377,59.27245489,58.82200393,60.10430588,60.90874661,61.51060014,61.74838059,63.28503148,61.12237542,60.87046418,61.23634728,60.99214796,60.18921274,60.07774571,61.20623845,61.65825197,60.11025633,60.52832382,61.18188688,61.31380433,58.80528487,57.84584698,58.73805752,54.85645345,58.79988199,60.07737149,56.20096342,60.3929374,36.77761826,49.22568866,55.10930206,65.24736292,57.08641006,54.08806036,53.89556268,53.5613321,53.51515767,52.30442805,52.24562597,53.50311397,53.49561038,53.53878528,49.66610081,52.35633014,55.17584864,53.945292,53.79353353,54.8626422,54.87102507,56.14098197,57.38968051,55.1146169,54.92290752,54.87858275,54.86639486,56.34316676,56.16200014,69.90905494,68.20948497,68.51263756,65.64670149,65.53992678,67.07185321,67.0542345,66.79344433,66.75400526,66.76640135,66.76742739,65.53052634,67.01174217,67.98329773,69.18915578,66.69019707,69.61506484,67.94096632,67.91401491,66.84415179,67.88935229,67.89356226,69.1984958,52.24244378,52.37211419,50.95591909,51.07641848,50.91919022,52.13500015,52.26717303,60.03109894,65.23341727,72.11099746,75.02859632,81.93540828,81.20708335,80.86208705,81.04817673,71.74669785,73.05200134,74.34519255,75.72326992,78.55812705,76.95800509,77.08696036,79.61302675,79.68123466,78.31207499,77.08036041,77.18815309,77.11523959,75.74423094,75.73143868,74.48319908,73.17138546,66.80804931,53.88772644,53.87714358,53.6088119,53.65411471,54.86536613,53.49300076,53.52447811,53.52000034,56.83649529,57.43503283,82.38440921,83.83190983,83.9128805,83.94305425,83.06892508,82.91998964,82.29555463,82.30635577,82.23464297,82.20709065,80.98821075,83.93336979,81.32873456,82.46698736,82.70592498,83.93335761,83.80821766,83.84313602,82.59867874,82.62361191,83.94865746,83.83137976,83.46075784,82.14902814,82.18902896,83.83722778,83.60064452,83.63187976,85.04806926,84.87213079,84.92473511,84.90790341,83.55500539,83.59501005,84.81195299,84.86952928,84.85600059,84.81955391,82.33120262,78.56908599,73.14783901,64.99883861,66.78701764,64.5916058,64.77055337,64.56918786,65.02605783,65.01019955,64.78145201,64.77581828,64.55221044,64.34285288,62.8764752,64.57949744,63.17957281,61.89857751,63.48365778,55.62801456,43.17986365])

我想找到这个信号的所有斜率。我尝试过一阶差分和二阶差分(np.diff 并取差值)。但是斜坡上的点会有每一个微小的差异,与开始或结束的点相比,差异更大。

这是我尝试过的

def detect_slope(signal,window_size = 3,threshold = 5):
    list_ = []
    for i in range(window_size,len(signal)-window_size):
        diff_ =  np.mean(signal[i-window_size:i]) - np.mean(signal[i:window_size+i])
        list_.append(diff_)
        
    first_order_diff = np.array(list_)    
    
    d = np.where(np.abs(first_order_diff) < threshold,first_order_diff)
    idx = np.where(np.abs(d) != 0)
    
    # might need some offset because we are doing some smoothing,but just use raw idx for Now
    
    # second order different
    diff_list = np.array(list_).copy()
    dd = np.diff(diff_list)
    print(dd.shape)
    dd_idx = np.where(np.abs(dd) > 0.5)
    
    return diff_list,dd,idx,dd_idx

我玩过一阶到二阶差异,但似乎没有任何效果。我试图找到所有的波峰和波谷,并排除所有的波峰和波谷,也排除所有这些波峰或具有足够接近值的邻居。

附件是我想要的输出。对不起,糟糕的照片。

enter image description here

解决方法

这里不清楚您想要什么,但如果您的问题是 diff 正在接收局部变化并且您想将注意力集中在全局变化上,请先平滑信号。

import numpy as np
import matplotlib.pyplot as plt
from scipy.signal import savgol_filter

plt.plot(x)
x = savgol_filter(x,21,3)
plt.plot(x)


diff_list,dd,idx,dd_idx = detect_slope(x)
plt.plot(diff_list)
plt.show()

这给 -

enter image description here

蓝色是您的原始信号,橙色是您的平滑信号,绿色是您的新 diff。您可以通过使用 savgol_filter 的两个参数将其设置为在不同级别接收更改。您越积极地平滑函数,导数获得的全局变化(和局部变化越少)就越多。

,

您可以尝试 scipy 的 find_peaks 函数。正如您猜测的那样,它会使定义参数的峰值或多或少变得敏感。在你的情况下最好的是突出(“在找到另一个高峰之前你必须下降多少”)。我使用你的函数,最大峰值为正,最小峰值为负。

import numpy as np
from matplotlib import pyplot as plt
from scipy.ndimage import median_filter
from scipy.signal import find_peaks
#Find peaks (maximum)
yhat = x
max_peaks,_ = find_peaks(yhat,prominence=10 )
min_peaks,_ = find_peaks(-yhat,prominence=10 )
#Plot data and max peak
fig,ax2 = plt.subplots(figsize=(20,10))
ax2.plot(max_peaks,yhat[max_peaks],"xr",markersize=20)
ax2.plot(min_peaks,yhat[min_peaks],markersize=20)
ax2.plot(yhat,'-')
ax2.plot(yhat,'o',markersize=4)

enter image description here

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。