如何用Javascript高效计算不同长度时间序列数组的均值
高效计算多组不同长度时间序列的时间戳均值(JavaScript)
针对你需要按时间戳对多组存在数据缺失的时间序列计算均值的需求,下面提供基于Lodash和原生JavaScript的两种高效实现方案:
核心思路
- 统计每个时间戳的数值总和与有效数据个数:用对象存储每个时间戳对应的数值总和和出现次数,遍历所有数组时更新这些统计值。
- 计算均值并转换为目标格式:基于统计结果计算每个时间戳的均值,再转换为
[时间戳, 均值]的数组格式,并按时间戳排序。
方案一:使用Lodash实现
const _ = require('lodash'); // 确保已安装并引入Lodash // 示例数据 const array1 = [[1, 100], [2, 200], [3, 300], [4, 400]]; const array2 = [[1, 150], [3, 350], [4, 450]]; const array3 = [[1, 250], [2, 350], [4, 450]]; const allArrays = [array1, array2, array3]; // 1. 统计每个时间戳的总和与数据个数 const timeStats = _.reduce(allArrays, (acc, currentArray) => { _.forEach(currentArray, ([time, value]) => { // 若该时间戳未初始化,创建统计对象 if (!acc[time]) { acc[time] = { sum: 0, count: 0 }; } acc[time].sum += value; acc[time].count += 1; }); return acc; }, {}); // 2. 计算均值、排序并格式化结果 const averageResult = _.chain(timeStats) .map(({ sum, count }, time) => [Number(time), sum / count]) .sortBy(0) // 按时间戳升序排列 .map(([time, avg]) => [time, Math.round(avg * 10) / 10]) // 保留1位小数,匹配示例格式 .value(); console.log(averageResult); // 输出:[[1, 166.7], [2, 275], [3, 325], [4, 433.3]]
方案二:原生JavaScript实现(无需Lodash)
如果不想依赖第三方库,原生JS同样可以高效完成:
// 示例数据 const array1 = [[1, 100], [2, 200], [3, 300], [4, 400]]; const array2 = [[1, 150], [3, 350], [4, 450]]; const array3 = [[1, 250], [2, 350], [4, 450]]; const allArrays = [array1, array2, array3]; // 1. 统计每个时间戳的总和与数据个数 const timeStats = {}; allArrays.forEach(currentArray => { currentArray.forEach(([time, value]) => { if (!timeStats[time]) { timeStats[time] = { sum: 0, count: 0 }; } timeStats[time].sum += value; timeStats[time].count += 1; }); }); // 2. 计算均值、排序并格式化结果 const averageResult = Object.entries(timeStats) .map(([time, { sum, count }]) => [Number(time), sum / count]) .sort((a, b) => a[0] - b[0]) // 按时间戳升序排序 .map(([time, avg]) => [time, Math.round(avg * 10) / 10]); console.log(averageResult); // 输出与Lodash方案一致
对你原有思路的修正说明
你原来的代码存在几个问题:
- 循环语法错误:
for (int i = 0; allArrays.length; i++)不符合JS语法,正确写法是for (let i = 0; i < allArrays.length; i++),且JS中没有int关键字。 - 转换对象的方向错误:你写的
toObject函数将数组转为了对象数组,但这不利于按时间戳分组,直接用时间戳作为键的对象存储统计数据才是更高效的方式。
内容的提问来源于stack exchange,提问作者Gabriel
相关产品推荐
相关产品推荐

