繁体   English   中英

阵列中每小时的平均值

[英]Average of every hour in a array

我有一个数组,每分钟更新一次。 当我想显示一天时,我希望获得当天每一小时的平均值。

最近一分钟是添加数组的末尾。

    //get the last elements from the array
    var hours= (this.today.getHours() + 1) * 60
    var data = Array.from(this.temps.data)
    let lastData = data.slice(Math.max(data.length - hours))

    let newData: any

    // calculate the average of every hour
    for (let i = 0; i < minutes; i++) {
      var cut = i * 60
      for (let i = cut; i < (cut + 60); i++) {
        newData = newData + lastData[i];
        let test = newData/60
        console.log(test);
      }
    }

我不知道如何从每60个元素中组成一个数组。 我的目标是得到一个像

avgHour[20,22,30,27,]

我拥有的阵列每分钟更新一次。 因此,我需要平均每60个元素才能获得一个小时。

数组看起来像这样

data[25,33,22,33]

一周中的每一分钟是如此之长。

这对我有用

    var arrays = [], size = 60;

    while (arr.length > 0){
        arrays.push(arr.splice(0, size));
    }

    for (let i = 0; i < (arrays.length - 1); i++) {
      var sum = 0
        for (let b = 0; b < 60; b++) {
          sum += arrays[i][b]
        }
        let avg = sum/60
        arr2.push(avg)            
    }

这只会每60个元素分割一次数组。 现在,我可以使用JavaScript计算每60个重复项的平均值。 如何将长数组拆分为较小的数组

谢谢您的帮助!

您可以按小时减少数据和分组,然后只需映射即可获得每小时的平均值。 我正在用一下时间来解析下面的日期,您可以使用任何喜欢的lib / js来实现。

 const arr = Array.from({length: 100}, () => ({time: moment().subtract(Math.floor(Math.random() * 10), 'hours'), value: Math.floor(Math.random() * 100)})); const grouped = [...arr.reduce((a, b) => { let o = a.get(b.time.get('hour')) || {value: 0, qty: 0}; a.set(b.time.get('hour'), {value: o.value + b.value, qty: o.qty + 1}); return a; }, new Map)].map(([k, v]) => ({ [k]: v.value / v.qty })); console.log(grouped) 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/moment.js/2.24.0/moment-with-locales.min.js"></script> 

为了测量平均值,我需要每60个元素拆分一次数组。 这是我找到的解决方案

//Calculate the average of every 60 elements to get the average of an hour
var arr2: number[] = []
var arr: number[] = []
arr = Array.from(this.temps.data)
var arrays = [], size = 60;

while (arr.length > 0){
    arrays.push(arr.splice(0, size));
}

for (let i = 0; i < (arrays.length - 1); i++) {
  var sum = 0
    for (let b = 0; b < 60; b++) {
      sum += arrays[i][b]
    }
    let avg = sum/60
    arr2.push(avg)            
}

毕竟,我认为获取数组的最后一个元素是愚蠢的,因为这是一个更好的解决方案。 但是,谢谢您的帮助!

通过分组然后减少,您可以按照以下步骤进行操作。

 function groupBy(list, keyGetter) { const map = {}; list.forEach((item) => { const key = keyGetter(item); if (!map[key]) { map[key] = [item]; } else { map[key].push(item); } }); return map; } const data = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]; const now = (new Date()).getTime(); const stepSize = 60000*1; const withTime = data.reverse().map((x, i) => { return { time: new Date(now - stepSize * i), temp: x } }); const grouped = groupBy(withTime, x => new Date(x.time.getFullYear(), x.time.getMonth(), x.time.getDate(), x.time.getHours()).valueOf()); const avg = Object.entries(grouped).map((x) => { return { time: new Date(Number(x[0])), temp: x[1].map(y => y.temp).reduce((acc, val) => acc + val) * (1.0 / x[1].length) } }); console.log(avg); 

我是函数式编程库Ramda的忠实粉丝。 (免责声明:我是它的作者之一。)我倾向于从简单,可重用的功能角度进行思考。

当我想到如何解决这个问题时,我是通过拉姆达的观点来考虑的。 我可能会这样解决这个问题:

 const avgHour = pipe( splitEvery(60), map(mean), ) // some random data const data = range(0, 7 * 24 * 60).map(_ => Math.floor(Math.random() * 20 + 10)) console.log(avgHour(data)) 
 <script src="//cdnjs.cloudflare.com/ajax/libs/ramda/0.26.1/ramda.js"></script> <script>const {pipe, splitEvery, map, mean, range} = R</script> 

我认为这是很容易理解的,至少在您了解管道创建了一系列函数之后,每个函数都会将其结果传递给下一个函数。

现在,通常没有理由包括像Ramda这样的大型图书馆来解决一个相当简单的问题。 但是该版本中使用的所有功能都易于重用。 因此,尝试创建自己的这些功能的版本并使它们对其余应用程序可用可能是有意义的。 实际上,这就是像Ramda这样的库实际上是如何构建的。

因此,这是一个具有这些功能的简单实现的版本,您可以将它们放置在实用程序库中:

 const pipe = (...fns) => (x) => fns.reduce((v, f) => f(v), x) const splitEvery = (n) => (xs) => { let i = 0, a = [] while (i < xs.length) {a.push(xs.slice(i, i + n)); i += n} return a } const map = (fn) => (xs) => xs.map(x => fn(x)) const sum = (xs) => xs.reduce((a, b) => a + b, 0) const mean = (xs) => sum(xs) / (xs.length || 1) const avgHour = pipe( splitEvery(60), map(mean) ) const range = (lo, hi) => [...Array(hi - lo)].map((_, i) => lo + i) // some random data const data = range(0, 7 * 24 * 60).map(_ => Math.floor(Math.random() * 20 + 10)) console.log(avgHour(data)) 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM