Javascript 数据整理:计算嵌套 json 中的百分比变化
Javascript data wrangling: Calculate percent change in a nested json
有一个 json 这种格式的文件...
data =[
{
key: "london",
values: [
{day: "2020-01-01", city: "london", value: 10},
{day: "2020-01-02", city: "london", value: 20},
{day: "2020-01-03", city: "london", value: 30},
{day: "2020-01-04", city: "london", value: 30},
{day: "2020-01-05", city: "london", value: 30},
{day: "2020-01-06", city: "london", value: 30}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", city: "berlin", value: 10},
{day: "2020-01-02", city: "berlin", value: 15},
{day: "2020-01-03", city: "berlin", value: 30},
{day: "2020-01-04", city: "berlin", value: 30},
{day: "2020-01-05", city: "berlin", value: 30},
{day: "2020-01-06", city: "berlin", value: 45}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", city: "rome", value: 10},
{day: "2020-01-02", city: "rome", value: 12},
{day: "2020-01-03", city: "rome", value: 6},
{day: "2020-01-04", city: "rome", value: 9},
{day: "2020-01-05", city: "rome", value: 27},
{day: "2020-01-06", city: "rome", value: 36}
]
}]
我想知道如何使用 javascript 计算系列中的每日百分比变化。我期待得到以下输出。如果可能,我想删除 city
以免重复信息。
data =[
{
key: "london",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-02", value: 20, perc: 1},
{day: "2020-01-03", value: 30, perc: 1},
{day: "2020-01-04", value: 30, perc: 0},
{day: "2020-01-05", value: 30, perc: 0},
{day: "2020-01-06", value: 30, perc: 0}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-02", value: 15, perc: 0.5},
{day: "2020-01-03", value: 30, perc: 1},
{day: "2020-01-04", value: 30, perc: 0},
{day: "2020-01-05", value: 30, perc: 0},
{day: "2020-01-06", value: 45, perc: 0.5}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-02", value: 12, perc: 0.2},
{day: "2020-01-03", value: 6, perc: -0.5},
{day: "2020-01-04", value: 9, perc: 0.5},
{day: "2020-01-05", value: 27, perc: 2},
{day: "2020-01-06", value: 36, perc: 0.33}
]
}]
奖金问题:我应该怎么做才能计算不同时间段(每两天、每星期等)的百分比变化并获得如下所示的输出? (每两天显示百分比变化)
data =[
{
key: "london",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-03", value: 30, perc: 2},
{day: "2020-01-05", value: 30, perc: 0},
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-03", value: 30, perc: 2},
{day: "2020-01-05", value: 30, perc: 0},
]
},
{
key: "rome",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-03", value: 6, perc: -0.4},
{day: "2020-01-05", value: 27, perc: 4.5},
]
}]
这是我对这种情况的看法。它还包括奖金问题。
P.S.: 这是我的第一个Whosebugpost,有什么问题欢迎追问!
// Your input data
const data = [
{
key: "london",
values: [
{day: "2020-01-01", city: "london", value: 10},
{day: "2020-01-02", city: "london", value: 20},
{day: "2020-01-03", city: "london", value: 30},
{day: "2020-01-04", city: "london", value: 30},
{day: "2020-01-05", city: "london", value: 30},
{day: "2020-01-06", city: "london", value: 30}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", city: "berlin", value: 10},
{day: "2020-01-02", city: "berlin", value: 15},
{day: "2020-01-03", city: "berlin", value: 30},
{day: "2020-01-04", city: "berlin", value: 30},
{day: "2020-01-05", city: "berlin", value: 30},
{day: "2020-01-06", city: "berlin", value: 45}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", city: "rome", value: 10},
{day: "2020-01-02", city: "rome", value: 12},
{day: "2020-01-03", city: "rome", value: 6},
{day: "2020-01-04", city: "rome", value: 9},
{day: "2020-01-05", city: "rome", value: 27},
{day: "2020-01-06", city: "rome", value: 36}
]
}];
// The parsed output data
const parsedData = data.map((obj) => {
// Maps the object values to calculate the percentage
return {...obj, values: obj.values.map((value, i) => {
// Delete the "city" key
delete value['city'];
// Can't calculate the percentage on the first element
if (i == 0)
return { ...value, perc: 0 };
// Get the current & previous day/value
const currentValue = value.value;
const currentDay = new Date(value.day);
const previousValue = obj.values[i-1].value;
const previousDay = new Date(obj.values[i-1].day);
// Calculate the days between the previous and current entry
const dayTimeDiff = Math.abs(currentDay - previousDay);
const dayDiff = Math.ceil(dayTimeDiff / (1000 * 60 * 60 * 24));
// Calculate the precentage = (current - previous) / previous
const percentDiff = currentValue - previousValue / previousValue / dayDiff;
return { ...value, perc: percentDiff };
})}
});
console.log(parsedData);
对于第一部分,您可以操作值数组中的每个值:
const data = [
{
key: "london",
values: [
{day: "2020-01-01", city: "london", value: 10},
{day: "2020-01-02", city: "london", value: 20},
{day: "2020-01-03", city: "london", value: 30},
{day: "2020-01-04", city: "london", value: 30},
{day: "2020-01-05", city: "london", value: 30},
{day: "2020-01-06", city: "london", value: 30}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", city: "berlin", value: 10},
{day: "2020-01-02", city: "berlin", value: 15},
{day: "2020-01-03", city: "berlin", value: 30},
{day: "2020-01-04", city: "berlin", value: 30},
{day: "2020-01-05", city: "berlin", value: 30},
{day: "2020-01-06", city: "berlin", value: 45}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", city: "rome", value: 10},
{day: "2020-01-02", city: "rome", value: 12},
{day: "2020-01-03", city: "rome", value: 6},
{day: "2020-01-04", city: "rome", value: 9},
{day: "2020-01-05", city: "rome", value: 27},
{day: "2020-01-06", city: "rome", value: 36}
]
}]
const newData = data.map((info) => {
const n = info.values.length;
const valuesCopy = info.values.map((info) => info.value);
for (let i = 0; i < n; i++) {
const currentValue = valuesCopy[i];
const previousValue = valuesCopy[i - 1];
// calculate the percentage
const percentage = (currentValue - previousValue) / previousValue;
// percentage is NaN return 0
// percentage is < 1, return 2 decimal places
// otherwise return percentage
info.values[i].value = !percentage ? 0 : percentage < 1 ? percentage.toFixed(2) : percentage;
}
return info;
})
console.log(JSON.stringify(newData, null, 2));
使用简单 for 循环 + 注释的示例:
const data =[
{
key: "london",
values: [
{day: "2020-01-01", city: "london", value: 10},
{day: "2020-01-02", city: "london", value: 20},
{day: "2020-01-03", city: "london", value: 30},
{day: "2020-01-04", city: "london", value: 30},
{day: "2020-01-05", city: "london", value: 30},
{day: "2020-01-06", city: "london", value: 30}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", city: "berlin", value: 10},
{day: "2020-01-02", city: "berlin", value: 15},
{day: "2020-01-03", city: "berlin", value: 30},
{day: "2020-01-04", city: "berlin", value: 30},
{day: "2020-01-05", city: "berlin", value: 30},
{day: "2020-01-06", city: "berlin", value: 45}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", city: "rome", value: 10},
{day: "2020-01-02", city: "rome", value: 12},
{day: "2020-01-03", city: "rome", value: 6},
{day: "2020-01-04", city: "rome", value: 9},
{day: "2020-01-05", city: "rome", value: 27},
{day: "2020-01-06", city: "rome", value: 36}
]
}
];
// Define resulting array
const results = [];
// Loop data
for(let i = 0; i < data.length; i++) {
// Set city object
const city = {
key: data[i].key,
values: []
};
// Set shorcut to values
const dVal = data[i].values
// Loop values in city entry
for(let i = 0; i < dVal.length; i++) {
// Set previous value or current if it is first cycle
const prev = (i !== 0) ? dVal[i-1].value : dVal[i].value;
// Set current value
const cur = dVal[i].value;
// Calculate percentage
let percDiff = (cur - prev) / prev;
// Fancy result as you need
percDiff = parseFloat(percDiff.toFixed(2));
// Push to city object
city.values.push({
day: dVal[i].day,
value: dVal[i].value,
perc: percDiff
});
}
// Push city object to resulting array
results.push(city);
}
// Log
console.log(results);
第二个问题的答案很简单——从数组中删除不需要的日条目,并将生成的数组传递给同一个函数。它计算条目之间的差异,无论是天还是周
有一个 json 这种格式的文件...
data =[
{
key: "london",
values: [
{day: "2020-01-01", city: "london", value: 10},
{day: "2020-01-02", city: "london", value: 20},
{day: "2020-01-03", city: "london", value: 30},
{day: "2020-01-04", city: "london", value: 30},
{day: "2020-01-05", city: "london", value: 30},
{day: "2020-01-06", city: "london", value: 30}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", city: "berlin", value: 10},
{day: "2020-01-02", city: "berlin", value: 15},
{day: "2020-01-03", city: "berlin", value: 30},
{day: "2020-01-04", city: "berlin", value: 30},
{day: "2020-01-05", city: "berlin", value: 30},
{day: "2020-01-06", city: "berlin", value: 45}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", city: "rome", value: 10},
{day: "2020-01-02", city: "rome", value: 12},
{day: "2020-01-03", city: "rome", value: 6},
{day: "2020-01-04", city: "rome", value: 9},
{day: "2020-01-05", city: "rome", value: 27},
{day: "2020-01-06", city: "rome", value: 36}
]
}]
我想知道如何使用 javascript 计算系列中的每日百分比变化。我期待得到以下输出。如果可能,我想删除 city
以免重复信息。
data =[
{
key: "london",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-02", value: 20, perc: 1},
{day: "2020-01-03", value: 30, perc: 1},
{day: "2020-01-04", value: 30, perc: 0},
{day: "2020-01-05", value: 30, perc: 0},
{day: "2020-01-06", value: 30, perc: 0}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-02", value: 15, perc: 0.5},
{day: "2020-01-03", value: 30, perc: 1},
{day: "2020-01-04", value: 30, perc: 0},
{day: "2020-01-05", value: 30, perc: 0},
{day: "2020-01-06", value: 45, perc: 0.5}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-02", value: 12, perc: 0.2},
{day: "2020-01-03", value: 6, perc: -0.5},
{day: "2020-01-04", value: 9, perc: 0.5},
{day: "2020-01-05", value: 27, perc: 2},
{day: "2020-01-06", value: 36, perc: 0.33}
]
}]
奖金问题:我应该怎么做才能计算不同时间段(每两天、每星期等)的百分比变化并获得如下所示的输出? (每两天显示百分比变化)
data =[
{
key: "london",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-03", value: 30, perc: 2},
{day: "2020-01-05", value: 30, perc: 0},
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-03", value: 30, perc: 2},
{day: "2020-01-05", value: 30, perc: 0},
]
},
{
key: "rome",
values: [
{day: "2020-01-01", value: 10, perc: 0},
{day: "2020-01-03", value: 6, perc: -0.4},
{day: "2020-01-05", value: 27, perc: 4.5},
]
}]
这是我对这种情况的看法。它还包括奖金问题。
P.S.: 这是我的第一个Whosebugpost,有什么问题欢迎追问!
// Your input data
const data = [
{
key: "london",
values: [
{day: "2020-01-01", city: "london", value: 10},
{day: "2020-01-02", city: "london", value: 20},
{day: "2020-01-03", city: "london", value: 30},
{day: "2020-01-04", city: "london", value: 30},
{day: "2020-01-05", city: "london", value: 30},
{day: "2020-01-06", city: "london", value: 30}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", city: "berlin", value: 10},
{day: "2020-01-02", city: "berlin", value: 15},
{day: "2020-01-03", city: "berlin", value: 30},
{day: "2020-01-04", city: "berlin", value: 30},
{day: "2020-01-05", city: "berlin", value: 30},
{day: "2020-01-06", city: "berlin", value: 45}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", city: "rome", value: 10},
{day: "2020-01-02", city: "rome", value: 12},
{day: "2020-01-03", city: "rome", value: 6},
{day: "2020-01-04", city: "rome", value: 9},
{day: "2020-01-05", city: "rome", value: 27},
{day: "2020-01-06", city: "rome", value: 36}
]
}];
// The parsed output data
const parsedData = data.map((obj) => {
// Maps the object values to calculate the percentage
return {...obj, values: obj.values.map((value, i) => {
// Delete the "city" key
delete value['city'];
// Can't calculate the percentage on the first element
if (i == 0)
return { ...value, perc: 0 };
// Get the current & previous day/value
const currentValue = value.value;
const currentDay = new Date(value.day);
const previousValue = obj.values[i-1].value;
const previousDay = new Date(obj.values[i-1].day);
// Calculate the days between the previous and current entry
const dayTimeDiff = Math.abs(currentDay - previousDay);
const dayDiff = Math.ceil(dayTimeDiff / (1000 * 60 * 60 * 24));
// Calculate the precentage = (current - previous) / previous
const percentDiff = currentValue - previousValue / previousValue / dayDiff;
return { ...value, perc: percentDiff };
})}
});
console.log(parsedData);
对于第一部分,您可以操作值数组中的每个值:
const data = [
{
key: "london",
values: [
{day: "2020-01-01", city: "london", value: 10},
{day: "2020-01-02", city: "london", value: 20},
{day: "2020-01-03", city: "london", value: 30},
{day: "2020-01-04", city: "london", value: 30},
{day: "2020-01-05", city: "london", value: 30},
{day: "2020-01-06", city: "london", value: 30}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", city: "berlin", value: 10},
{day: "2020-01-02", city: "berlin", value: 15},
{day: "2020-01-03", city: "berlin", value: 30},
{day: "2020-01-04", city: "berlin", value: 30},
{day: "2020-01-05", city: "berlin", value: 30},
{day: "2020-01-06", city: "berlin", value: 45}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", city: "rome", value: 10},
{day: "2020-01-02", city: "rome", value: 12},
{day: "2020-01-03", city: "rome", value: 6},
{day: "2020-01-04", city: "rome", value: 9},
{day: "2020-01-05", city: "rome", value: 27},
{day: "2020-01-06", city: "rome", value: 36}
]
}]
const newData = data.map((info) => {
const n = info.values.length;
const valuesCopy = info.values.map((info) => info.value);
for (let i = 0; i < n; i++) {
const currentValue = valuesCopy[i];
const previousValue = valuesCopy[i - 1];
// calculate the percentage
const percentage = (currentValue - previousValue) / previousValue;
// percentage is NaN return 0
// percentage is < 1, return 2 decimal places
// otherwise return percentage
info.values[i].value = !percentage ? 0 : percentage < 1 ? percentage.toFixed(2) : percentage;
}
return info;
})
console.log(JSON.stringify(newData, null, 2));
使用简单 for 循环 + 注释的示例:
const data =[
{
key: "london",
values: [
{day: "2020-01-01", city: "london", value: 10},
{day: "2020-01-02", city: "london", value: 20},
{day: "2020-01-03", city: "london", value: 30},
{day: "2020-01-04", city: "london", value: 30},
{day: "2020-01-05", city: "london", value: 30},
{day: "2020-01-06", city: "london", value: 30}
]
},
{
key: "berlin",
values: [
{day: "2020-01-01", city: "berlin", value: 10},
{day: "2020-01-02", city: "berlin", value: 15},
{day: "2020-01-03", city: "berlin", value: 30},
{day: "2020-01-04", city: "berlin", value: 30},
{day: "2020-01-05", city: "berlin", value: 30},
{day: "2020-01-06", city: "berlin", value: 45}
]
},
{
key: "rome",
values: [
{day: "2020-01-01", city: "rome", value: 10},
{day: "2020-01-02", city: "rome", value: 12},
{day: "2020-01-03", city: "rome", value: 6},
{day: "2020-01-04", city: "rome", value: 9},
{day: "2020-01-05", city: "rome", value: 27},
{day: "2020-01-06", city: "rome", value: 36}
]
}
];
// Define resulting array
const results = [];
// Loop data
for(let i = 0; i < data.length; i++) {
// Set city object
const city = {
key: data[i].key,
values: []
};
// Set shorcut to values
const dVal = data[i].values
// Loop values in city entry
for(let i = 0; i < dVal.length; i++) {
// Set previous value or current if it is first cycle
const prev = (i !== 0) ? dVal[i-1].value : dVal[i].value;
// Set current value
const cur = dVal[i].value;
// Calculate percentage
let percDiff = (cur - prev) / prev;
// Fancy result as you need
percDiff = parseFloat(percDiff.toFixed(2));
// Push to city object
city.values.push({
day: dVal[i].day,
value: dVal[i].value,
perc: percDiff
});
}
// Push city object to resulting array
results.push(city);
}
// Log
console.log(results);
第二个问题的答案很简单——从数组中删除不需要的日条目,并将生成的数组传递给同一个函数。它计算条目之间的差异,无论是天还是周