Интерполирование «пропущенных лет» в JavaScript?

#javascript #algorithm #csv #interpolation

#javascript #алгоритм #csv #интерполяция

Вопрос:

Перед:

 id   year  value
SE   1950  67
SE   1960  71
SE   1965  82
NO   1975  65
NO   1985  75
  

После:

 data : {
    SE : {
        data : {
             1950 : 67,
             1951 : 67.4,
             1952 : 67.8,
             [...]
             1965 : 82
        },
        min_year : 1950,
        max_year : 1965

    }    
    NO : {
        data : {
             [...]
        },
        [...]   
    }    
} 
  

Итак, в принципе, каков наиболее эффективный способ заполнения пробелов / интерполяции на основе смежных значений в JS?

Ответ №1:

В JS как языке нет инструментов, которые могли бы помочь вам напрямую.

Вы можете довольно легко реализовать линейную или полиномиальную интерполяцию. Многочлен (скажем, степени 3), вероятно, обеспечит несколько более точные числа в середине, хотя конечные точки могут быть проблематичными — зависит от данных.

Линейная интерполяция проще, хотя в целом я бы предположил, что она не даст такой точной оценки, как интерполяция полиномом более высокой степени.

Альтернативой могут быть сплайны (кубические относительно просты), которые будут более чем достаточно точными для ваших целей. Это может быть небольшим излишеством, хотя, возможно, и нет — не уверен в объеме этого требования.

Вы могли бы рассмотреть возможность выполнения этого на стороне сервера и использования одной из многих библиотек для других языков, которые реализуют эти интерполяционные функции. Это дало бы вам действительно точный и общий способ эффективного решения проблемы без необходимости реализовывать его самостоятельно.

Трудно сказать, поскольку степень точности, диапазон данных и масштаб проекта зависят от того, какой тип интерполяции вам нужен, может ли это быть выполнено на стороне сервера / клиента и т.д.

Ответ №2:

Если вам просто нужна прямая линейная интерполяция, то задаются n_0 и n_1 в виде индексов, для которых вы знаете значения:

 val[n] = val[n_0]   (n - n_0) * (val[n_1] - val[n_0]) / (n_1 - n_0);
  

Учитывая ваши данные для SE, например, интерполированное значение для 1960 года будет равно:

 67.8   (1960 - 1952) * (82 - 67.8) / (1965 - 1952)
  

т. е. о 76.5

Комментарии:

1. Спасибо @Alnitak. Можете ли вы помочь мне дополнительно, описав функцию, которая возвращает «заполненный пробелами массив» при задании [{год: 1950, значение: 50},{год: 1955, значение: 55}, {год: 1970, значение: 65}]? Т.е. возвращаемый массив должен содержать 20 элементов.

2. вы используете неправильную структуру данных — поскольку она индексируется целым числом, вы должны использовать массив, а не объект.