【问题标题】:I have a data of temperatures for each month of a hundred years. How do I calculate the average of the temperatures for each year?我有一百年每个月的温度数据。如何计算每年的平均温度?
【发布时间】:2016-08-25 09:19:41
【问题描述】:

我知道这是一个菜鸟问题,对此表示歉意。但我有以下格式的数据列表:

{
    "Year": 1881,
    "Jan": -8,
    "Feb": -13,
    "Mar": 2,
    "Apr": -2,
    "May": -3,
    "Jun": -27,
    "Jul": -5,
    "Aug": -1,
    "Sep": -8,
    "Oct": -18,
    "Nov": -25,
    "Dec": -14,
    "J-D": -10,
    "D-N": -11,
    "DJF": -13,
    "MAM": -1,
    "JJA": -11,
    "SON": -17
},
{
    "Year": 1882,
    "Jan": 10,
    "Feb": 10,
    "Mar": 2,
    "Apr": -19,
    "May": -17,
    "Jun": -24,
    "Jul": -9,
    "Aug": 5,
    "Sep": 0,
    "Oct": -21,
    "Nov": -20,
    "Dec": -24,
    "J-D": -9,
    "D-N": -8,
    "DJF": 2,
    "MAM": -11,
    "JJA": -9,
    "SON": -14
},

等等

我想计算每年的平均温度。有100多年。最简单的方法是什么?将它们放入数组中并手动计算它们会花费太长时间。即使那样,我也不知道如何将平均温度分配给每年。我可以用什么方法编写这段代码?我正在使用 Javascript。

【问题讨论】:

  • 将一年中每个月的所有温度相加并除以 12 - 这就是平均值的计算方式
  • 谢谢,但是有很多年了。
  • @studious——你必须迭代来获取临时值,所以实现它以获得正确的结果。只有这样,如果您有性能问题,才需要修复它们。 100 年的价值不应该花很长时间。
  • 我不会担心这里的性能。 100年并不多。计算机速度很快
  • @Phil,谢谢。其他字段也似乎是平均值,但在几个月内(例如,“MAM”=3-5 月;“JJA”=6-8 月;“SON”=9-11 月)。有些不符合我的预期,直到我意识到它们是包括前一年月份在内的平均值(例如,“D-N”=上一个 12 月到现在的 11 月;“DJF”=上一个 12 月到现在的 2 月)。

标签: javascript arrays


【解决方案1】:

首先,您需要一个键数组来表示月份(这样您就可以忽略所有其他数据)

let months = ['Jan', 'Feb', 'Mar', ...];

然后,假设您的数据在一个实际的数组中,您可以使用 reduce operation(嗯,两个 reduce 操作)来生成平均年份的地图

let years = [{"Year":1881,"Jan":-8,"Feb":-13,"Mar":2,"Apr":-2,"May":-3,"Jun":-27,"Jul":-5,"Aug":-1,"Sep":-8,"Oct":-18,"Nov":-25,"Dec":-14,"J-D":-10,"D-N":-11,"DJF":-13,"MAM":-1,"JJA":-11,"SON":-17},{"Year":1882,"Jan":10,"Feb":10,"Mar":2,"Apr":-19,"May":-17,"Jun":-24,"Jul":-9,"Aug":5,"Sep":0,"Oct":-21,"Nov":-20,"Dec":-24,"J-D":-9,"D-N":-8,"DJF":2,"MAM":-11,"JJA":-9,"SON":-14}];

let months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];

let averages = years.reduce((avgs, year) => {
    let sum = months.reduce((avg, month) => avg + year[month], 0);
    avgs[year.Year] = sum / months.length;
    return avgs;
}, {});

document.write('<pre>' + JSON.stringify(averages, null, '  ') + '</pre>');

【讨论】:

  • 这与我想出的几乎相同。在此处发布为可运行的 sn-p 比在其他地方发布要好得多。
  • @RobG 我只是讨厌将初始数据放在可运行的 sn-ps 中
  • @RobG 完成。希望 sn-p 编辑器中有一个隐藏的“初始数据”部分
  • 是的,也许是一个建议箱。 :-)
【解决方案2】:

这是一个使用现代数组方法的答案,通过将问题分解为多个步骤,使解决方案更易于阅读。

// The data you provided
var data = [
    {
        "Year": 1881,
        "Jan": -8,
        "Feb": -13,
        "Mar": 2,
        "Apr": -2,
        "May": -3,
        "Jun": -27,
        "Jul": -5,
        "Aug": -1,
        "Sep": -8,
        "Oct": -18,
        "Nov": -25,
        "Dec": -14,
        "J-D": -10,
        "D-N": -11,
        "DJF": -13,
        "MAM": -1,
        "JJA": -11,
        "SON": -17
    },
    {
        "Year": 1882,
        "Jan": 10,
        "Feb": 10,
        "Mar": 2,
        "Apr": -19,
        "May": -17,
        "Jun": -24,
        "Jul": -9,
        "Aug": 5,
        "Sep": 0,
        "Oct": -21,
        "Nov": -20,
        "Dec": -24,
        "J-D": -9,
        "D-N": -8,
        "DJF": 2,
        "MAM": -11,
        "JJA": -9,
        "SON": -14
    },
];

// Hardcode which keys count towards the average, ignore the rest like "Year"
// and "J-D".
var months = 'Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec'.split(' ');

var result = data.map(yearData => ({     // Set `result` to `data` with each
                                         // item replaced with an object with...
    Year: yearData.Year,                 // The `Year` property copied
    average: (months                     // An `average` property set to the
                                         // result of taking `months` and...
        .map(month => yearData[month])   // Replacing each item with the value
                                         // at that key in the current year data
        .reduce((a, b) => a + b)         // Then taking the sum of the Array
        / months.length                  // Then going from sum to average by
                                         // dividing by the number of items
    ),
}));

// `result` now contains the averages.

有很多方法可以解决这个问题,但这不是唯一的解决方案。每种方法的共同点是,以一种或另一种方式,您需要遍历数组(由mapreduce 完成),像你一样存储总和(这里由reduce 隐式处理) ,然后除以月数。

【讨论】:

    【解决方案3】:

    或者

    jsFiddle

    var temps = [
    { "Year": 1881, "Jan": -8, "Feb": -13, "Mar": 2, "Apr": -2, "May": -3, "Jun": -27, "Jul": -5, "Aug": -1, "Sep": -8, "Oct": -18, "Nov": -25, "Dec": -14, "J-D": -10, "D-N": -11, "DJF": -13, "MAM": -1, "JJA": -11, "SON": -17 },
    { "Year": 1882, "Jan": 10, "Feb": 10, "Mar": 2, "Apr": -19, "May": -17, "Jun": -24, "Jul": -9, "Aug": 5, "Sep": 0, "Oct": -21, "Nov": -20, "Dec": -24, "J-D": -9, "D-N": -8, "DJF": 2, "MAM": -11, "JJA": -9, "SON": -14 }
    ],
    total = 0;
    
    for(var i=0, lng = temps.length; i < lng; ++i){
        var y = temps[i],
      	yearAvg = parseFloat(((y.Jan + y.Feb + y.Mar + y.Apr + y.May + y.Jun + y.Jul + y.Aug + y.Sep + y.Oct + y.Nov + y.Dec ) / 12).toFixed(2), 10);
        console.log(y.Year + ' average = ' + yearAvg);
      total += yearAvg;
    }
    
    document.getElementById('result').innerHTML = 'Total Avergae: ' + total/temps.length;
    &lt;div id="result"&gt;&lt;/div&gt;

    【讨论】:

      【解决方案4】:

      我建议编写一个 python 脚本将字符串解析为多维字典。 dict 的第一层应该是表示年份的键,值应该保存第二层字典,其中键是一年中的月份,值是相关的温度。从那里您可以编写一个函数来遍历 dict 并按照 Jaromanda 的建议计算平均值。

      我会为你写出来,但这是一个很好的学习项目。查找python多维字典以及如何解析字符串。

      【讨论】:

      • 为什么要为标记为 JavaScript 的问题提供 Python 解决方案?
      • 我正在提供我认为可以很好地解决他遇到的问题的方法。考虑到他是编写代码的新手,我认为使用 python 是有意义的,因为它不难学习并让它做你想做的事。除此之外,在 Web 开发方面,Python 是一门很棒的后端语言,也是开始进行一般编码的绝佳方式。 Javascript 主要用于 Web 开发,与基本的数字运算相对,此外,当您几乎没有经验时,与 python 相比,它是一种棘手的语言。
      猜你喜欢
      • 2019-11-15
      • 2021-12-20
      • 1970-01-01
      • 1970-01-01
      • 2023-01-27
      • 2019-07-28
      • 2023-03-15
      • 2021-12-18
      • 2016-06-22
      相关资源
      最近更新 更多