Я работаю в Javascript / React
с массивом объектов, содержащих спортивные данные.
Вот пример данных, с которыми я работаю:
const mydata = [
{ name: "Tom", year: 2018, statA: 23.2, statB: 12.3 },
{ name: "Bob", year: 2018, statA: 13.2, statB: 10.1 },
{ name: "Joe", year: 2018, statA: 18.2, statB: 19.3 },
{ name: "Tim", year: 2018, statA: 21.1, statB: 21.3 },
{ name: "Jim", year: 2018, statA: 12.5, statB: 32.4 },
{ name: "Nik", year: 2017, statA: 23.6, statB: 23.8 },
{ name: "Tre", year: 2017, statA: 37.8, statB: 18.3 },
{ name: "Ton", year: 2017, statA: 15.3, statB: 12.1 },
{ name: "Bil", year: 2017, statA: 32.2, statB: 41.3 },
{ name: "Geo", year: 2017, statA: 21.5, statB: 39.8 }
];
Моя проблема манипулирования данными здесь очень сложная, и я изо всех сил.Мне нужно масштабировать (чтобы обозначить 0, stdev 1) по годам каждый из нескольких ключей в моих данных (statA, statB).
Например, глядя на значения для year === 2018
в столбце statA, мы имеем [23.2, 13.2, 18.2, 21.1, 12.5].В качестве теста, подключение этого вектора к функции scale () R дает следующее:
scale(c(23.2, 13.2, 18.2, 21.1, 12.5))
[,1]
[1,] 1.1765253
[2,] -0.9395274
[3,] 0.1184989
[4,] 0.7321542
[5,] -1.0876511
attr(,"scaled:center")
[1] 17.64
attr(,"scaled:scale")
[1] 4.72578
... поэтому в моем исходном массиве объектов значение statA: 23.2 в первом объекте должно быть обновлено как1.1765, поскольку значение 23.2 на 1.1765 стандартных отклонений выше среднего для всех других значений statA, где Год == 2018. В моем полном наборе данных у меня ~ 8K объектов и ~ 50 ключей в каждом объекте, ~ 40 из которых мне нужно масштабироватьпо годам.
На высоком уровне, я думаю, мне нужно (1-е) вычислить среднее и st dev для каждого показателя за каждый год, и (2-е) использовать среднее и st dev для этого показателя для этогогод, и сопоставьте его с его масштабированным значением.Производительность / скорость важны для моего приложения, и я беспокоюсь, что обычный цикл for будет очень медленным, хотя сейчас я пытаюсь это сделать.
Любая помощь с этим приветствуется!
РЕДАКТИРОВАТЬ 2:
прежде чем я прочитал / закодировал на своем конце, хотел опубликовать то, что я закончил вчера:
const scaleCols = ['statA', 'statB'];
const allYears = [...new Set(rawData.map(ps => ps.Year))];
// loop over each year of the data
for(var i = 0; i < allYears.length; i++) {
// compute sums and counts (for mean calc)
thisYearsArray = rawData.filter(d => d.Year === allYears[i])
sums = {}, counts = {};
for(var j = 0; j < thisYearsArray.length; j++) {
for(var k = 0; k < scaleCols.length; k++) {
if(!(scaleCols[k] in sums)) {
sums[scaleCols[k]] = 0;
counts[scaleCols[k]] = 0;
}
sums[scaleCols[k]] += thisYearsArray[j][scaleCols[k]];
counts[scaleCols[k]] += 1;
}
}
console.log('sums', sums)
console.log('counts', counts)
}
... какя сказал не очень хорошо.
Редактировать: Помогут ли в этом функции масштабирования d3?