标准化嵌套字典中所有键的值,并追加为新的键/值对

问题描述

我有一本带有嵌套子词典的字典:

let dict = 
{
    "SEATTLE" :     {
        "gross_sales" : 106766,"price" : 584.50,"dates" : [             {
                "date" : "2020-03-13","total_sales_to_date" : 2,"new_sales" : 2,},{
                "date" : "2020-03-19","total_sales_to_date" : 5,"new_sales" : 3,}
 ]
    },"PHOENIX" :     {
        "gross_sales" : 26691.5,"price" : 292.25,"total_sales_to_date" : 9,"new_sales" : 9,"total_sales_to_date" : 19,"new_sales" : 10,}
 ]
    }

}

我想针对其他键/值对键/值对中的每个数值进行归一化,然后将其附加为 new 键/值对。

对于dates时间序列数据数组,我想针对两个日期(数组内)和同一日期的其他位置(其他对象)对每个日期中的每个键/值对进行归一化)。

例如,这是手术后我要寻找的东西:

{
    "SEATTLE" :     {
        "gross_sales" : 106766,"normalised_gross_sales" : 1.0,"normalised_price" : 1.0,"norm_total_sales_over_time" : 0.4,"norm_total_sales_over_locations" : 0.22222222,"norm_total_sales_over_time" : 1.0,"norm_total_sales_over_locations" : 0.26315789,"normalised_gross_sales" : 0.25,"normalised_price" : 0.5,"norm_total_sales_over_time" : 0.47368421,"norm_total_sales_over_locations" : 1.0,}
 ]
    }

}

即:数组中最后一个日期的total_sales_to_date值应标准化为1.0的{​​{1}}

,并且数组中当前日期的所有对象(norm_total_sales_over_timetotal_sales_to_date)的最大SEATTLE值应归一化为PHOENIX

我发现这在JS中处理起来非常复杂。我的实际任务是将字典与数百个子字典进行比较,我正在寻找一种可扩展的解决方案。在norm_total_sales_over_locations pandas中,这是微不足道的,但是,我想学习如何使用现代javascript处理此问题,因为我正在使用{{1 }}解释器。

什么是有效的dataframe JavaScript解决方案?

解决方法

以下是一种以上述方式返回标准化值的解决方案:

let dict = {
  "SEATTLE": {
    "gross_sales": 106766,"price": 584.50,"dates": [{
      "date": "2020-03-13","total_sales_to_date": 2,"new_sales": 2,},{
      "date": "2020-03-19","total_sales_to_date": 5,"new_sales": 3,}]
  },"PHOENIX": {
    "gross_sales": 26691.5,"price": 292.25,"total_sales_to_date": 9,"new_sales": 9,"total_sales_to_date": 19,"new_sales": 10,}]
  }

}


async function normaliseDict(_dict) {

  let values = await Object.values(_dict);
  // make arrays with values from each key
  let all_gross_sales = [];
  let all_price = [];
  let all_total_sales = {};

  values.forEach((element) => {
    all_gross_sales.push(element.gross_sales);
    all_price.push(element.price);

    let most_recent_total_sales_value = element.dates[element.dates.length - 1].total_sales_to_date;

    element.dates.forEach((date,idx) => {
      date.norm_total_sales_over_time = date.total_sales_to_date / most_recent_total_sales_value;
      if (all_total_sales[date.date]) all_total_sales[date.date].push(date.total_sales_to_date);
      else {
        all_total_sales[date.date] = [];
        all_total_sales[date.date].push(date.total_sales_to_date);
      }
    });

  });

  const newDict = values.map(ob => {
    ob.gross_sales_norm = ob.gross_sales / Math.max(...all_gross_sales);
    ob.price_norm = ob.price / Math.max(...all_price);
    return ob;
  });

  values.forEach((element) => {
    element.dates.forEach((date,idx) => {
      date.norm_total_sales_over_locations_for_this_date = date.total_sales_to_date / Math.max(...all_total_sales[date.date]);
    });
  });
  return await dict;
}


(async () => {
  console.log(await normaliseDict(dict))
})()