【问题标题】:How to detect peaks in a given 1D array in javascript?如何在javascript中检测给定一维数组中的峰值?
【发布时间】:2018-03-15 16:24:15
【问题描述】:

我有 (y) 值的数组。这些值范围并生成类似Graph

的图表

我想获取那个数组并获取 P、Q、R、S 和 T 属性的索引。

如果您想知道这些属性的含义。检查此图像以说明数组的哪一部分引用了该属性:P, Q, R, S, T

假设我们有一个像这样的 y 值数组:

const Data = [
  0, 0, 0, 0, 0.0000050048828125, 0.0000137939453125, 0.000049560546875,
  0.00008740234375, 0.00015966796875, 0.000262451171875, 0.0003975830078125, 0.0005687255859375,
  0.0007802734375, 0.001037353515625, 0.0013468017578125, 0.00172119140625, 0.0021756591796875,
  0.0027232666015625, 0.0033880615234375, 0.004206787109375, 0.0052380371093750005,
  0.006586181640625, 0.008400146484375001, 0.010904296875, 0.0144892578125, 0.0196798095703125,
  0.049684204101562504, 0.0886883544921875, 0.11185363769531251, 0.134164306640625,
  0.137352294921875, 0.1160369873046875, 0.08516308593750001, 0.0539765625,
  0.014997436523437501, -0.015882568359375, -0.0387554931640625, -0.06125732421875, -0.0745780029296875, -0.07479357910156251, -0.0725338134765625, -0.0418538818359375,
  0.08582861328125001, 0.397717529296875, 0.8136408691406251, 1.2295617980957032,
  0.9944150390625001, 0.2824605712890625, -0.38949267578125, -0.597251220703125, -0.425675537109375, -0.1537947998046875, -0.0500914306640625, -0.0111041259765625,
  0.0027451171875, 0.0071739501953125, 0.008443359375, 0.0094327392578125, 0.012530517578125,
  0.0176046142578125, 0.0300162353515625, 0.0433489990234375, 0.056962646484375004,
  0.0704832763671875, 0.0770511474609375, 0.0898175048828125, 0.10311853027343751,
  0.117046142578125, 0.1312630615234375, 0.1529300537109375, 0.167607177734375,
  0.1899068603515625, 0.2124422607421875, 0.235044677734375, 0.2575535888671875,
  0.2724073486328125, 0.286978271484375, 0.3007579345703125, 0.3067425537109375,
  0.3106370849609375, 0.303756103515625, 0.2897236328125, 0.25916931152343753,
  0.2200599365234375, 0.1728209228515625, 0.133416259765625, 0.086224853515625,
  0.05493408203125, 0.02409423828125, 0.00922607421875, -0.0043409423828125, -0.0097349853515625, -0.013127685546875, -0.01423095703125, -0.013834716796875, -0.012556030273437501, -0.010675048828125, -0.00835888671875, -0.0057305908203125, -0.0000562744140625
]

根据上面的值,我想获取属性的索引。

我们有这个框架slayerjs,它基本上可以检测峰值。但它只返回给定点数组的最高峰。

【问题讨论】:

  • 所以编写循环它的代码,当它下降时,再次上升,你知道你有一个高峰......
  • 但有时我们可能有不同的数据点,这意味着我的条件在大多数情况下都不会满足@epascarello
  • 减少点数得到感兴趣区间的峰值
  • 在大多数情况下,我们可能有 1000 个点。我不能处理静态数组。数据点是根据时间限制生成的@Juan
  • 可能是 30 秒、1 分钟甚至 10 分钟

标签: javascript arrays node.js search graph


【解决方案1】:

我的看法:

  1. 计算出所有波浪(向上或向下),指数穿过 y 轴 = 0。

  2. 根据第1步的结果,我们可以计算出P、Q、R、S。

例如:假设第1步的结果是one array=found。

如果found[index]是上波,found[index-1]found[index+1]是下波,那么我们就知道found[index]是一个Q。

以下是代码:

const test = [
  0, 0, 0, 0, 0.0000050048828125, 0.0000137939453125, 0.000049560546875,
  0.00008740234375, 0.00015966796875, 0.000262451171875, 0.0003975830078125, 0.0005687255859375,
  0.0007802734375, 0.001037353515625, 0.0013468017578125, 0.00172119140625, 0.0021756591796875,
  0.0027232666015625, 0.0033880615234375, 0.004206787109375, 0.0052380371093750005,
  0.006586181640625, 0.008400146484375001, 0.010904296875, 0.0144892578125, 0.0196798095703125,
  0.049684204101562504, 0.0886883544921875, 0.11185363769531251, 0.134164306640625,
  0.137352294921875, 0.1160369873046875, 0.08516308593750001, 0.0539765625,
  0.014997436523437501, -0.015882568359375, -0.0387554931640625, -0.06125732421875, -0.0745780029296875, -0.07479357910156251, -0.0725338134765625, -0.0418538818359375,
  0.08582861328125001, 0.397717529296875, 0.8136408691406251, 1.2295617980957032,
  0.9944150390625001, 0.2824605712890625, -0.38949267578125, -0.597251220703125, -0.425675537109375, -0.1537947998046875, -0.0500914306640625, -0.0111041259765625,
  0.0027451171875, 0.0071739501953125, 0.008443359375, 0.0094327392578125, 0.012530517578125,
  0.0176046142578125, 0.0300162353515625, 0.0433489990234375, 0.056962646484375004,
  0.0704832763671875, 0.0770511474609375, 0.0898175048828125, 0.10311853027343751,
  0.117046142578125, 0.1312630615234375, 0.1529300537109375, 0.167607177734375,
  0.1899068603515625, 0.2124422607421875, 0.235044677734375, 0.2575535888671875,
  0.2724073486328125, 0.286978271484375, 0.3007579345703125, 0.3067425537109375,
  0.3106370849609375, 0.303756103515625, 0.2897236328125, 0.25916931152343753,
  0.2200599365234375, 0.1728209228515625, 0.133416259765625, 0.086224853515625,
  0.05493408203125, 0.02409423828125, 0.00922607421875, -0.0043409423828125, -0.0097349853515625, -0.013127685546875, -0.01423095703125, -0.013834716796875, -0.012556030273437501, -0.010675048828125, -0.00835888671875, -0.0057305908203125, -0.0000562744140625
];

//calc the result for Step 1
step1 = test.reduce(function(pre, cur, index, orgArray){
  if(cur === 0){pre['found'].push({'type':'no-signal','index':index,'value':0});pre['min']={'value':0,'index':0};pre['max']={'value':0,'index':0};return pre;}
  if(pre['max']['value'] < cur) {
    pre['max']={'value':cur,'index':index};
    if(pre['max']['value']>orgArray[index+1]){pre['found'].push({'type':'upwave','index':index,'value':cur})};
  }
  if(pre['min']['value'] > cur) {
    pre['min']={'value':cur,'index':index};
    if(pre['min']['value']<orgArray[index+1]){pre['found'].push({'type':'downwave', 'index':index,'value':cur})};
  }
  if(orgArray[index-1] > 0 && cur < 0){pre['found'].push({'type':'down-cross','index':index});pre['min']={'value':0,'index':0};pre['max']={'value':0,'index':0};}
  if(orgArray[index-1] < 0 && cur > 0){pre['found'].push({'type':'up-cross','index':index});pre['max']={'value':0,'index':0};pre['min']={'value':0,'index':0};}
  return pre
},{'max':{'value':0,'index':0}, 'min':{'value':0,'index':0}, 'found':[]})

//console.log(step1['found']);

//Calc the final result
final = step1['found'].reduce(function(pre, cur, index, orgArray){
  if(cur.type==='downwave' 
    && orgArray[index-1].type==='down-cross' 
    && orgArray[index-2].type==='upwave' ) {
    pre.push({'type':'S', 'index':cur.index, 'value':cur.value});
  }
  if(cur.type==='downwave' 
    && (index+1 < orgArray.length && orgArray[index+1].type==='up-cross' )
    && (index+1 < orgArray.length && orgArray[index+2].type==='upwave') ) {
    pre.push({'type':'Q', 'index':cur.index, 'value':cur.value});
  }
  if(cur.type==='upwave' 
    && orgArray[index-1].type==='up-cross' 
    && (index+1 < orgArray.length && orgArray[index+1].type==='down-cross') ) {
    pre.push({'type':'R', 'index':cur.index, 'value':cur.value});
  }
  return pre;
}, []);
console.log(final);

【讨论】:

  • 假设我们有一个 1000 个点的数组,这个数组有 500 个 P、Q、R、S。这是否意味着结果变量只会捕获那些?
  • 另外,您能否尝试为找到的每个值命名属性。这样应该很容易看到。很抱歉给您带来麻烦,到目前为止,您做得很好。我要测试一下
  • @Katie,对于第一个问题,result['found'] 存储所有波的索引并且索引交叉 y=0)。所以我们可以从这个数组中计算出 P,Q,R,S。对于第二个问题,我不确定你的意思,result['found'] 的每一项都有一个名称来表示它是哪种索引。
  • 所以找到的是一组属性(即峰)。那么如果我们在一个数组中有多个 PQRS,result[found] 会存储它们吗?
  • 我在excel中画了一张图表,结果似乎匹配。所以下一步很容易,只需从result['found'] 计算出 P,Q,R,S;例如:result['found'][1] 是'upwave',result['found'][2] 是'downcross',所以result['found'] 是P。
猜你喜欢
  • 2021-07-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-09
  • 2013-05-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多