Я пытаюсь преобразовать один диапазон чисел в другой, сохраняя соотношение. Математика не моя сильная сторона.
У меня есть файл изображения, где значения точек могут варьироваться от -16000.00 до 16000.00, хотя типичный диапазон может быть намного меньше. Я хочу сжать эти значения в целочисленный диапазон 0-100, где 0 - это значение самой маленькой точки, а 100 - значение самой большой. Все промежуточные точки должны сохранять относительное соотношение, даже если теряется некоторая точность. Я хотел бы сделать это в python, но даже общего алгоритма должно быть достаточно. Я бы предпочел алгоритм, в котором мин / макс или любой диапазон может быть скорректирован (т. Е. Второй диапазон может быть от -50 до 800 вместо 0 до 100).
Ответы:
Или немного более читабельным:
Или, если вы хотите защитить для случая, когда старый диапазон равен 0 ( OldMin = OldMax ):
Обратите внимание, что в этом случае мы вынуждены выбрать одно из возможных новых значений диапазона произвольно. В зависимости от контекста разумным выбором могут быть:
NewMin
( см. Образец )NewMax
или(NewMin + NewMax) / 2
источник
Это простое линейное преобразование.
Таким образом, преобразование 10000 по шкале от -16000 до 16000 в новую шкалу от 0 до 100 дает:
источник
На самом деле, есть несколько случаев, когда вышеприведенные ответы будут нарушены Например, неверно введенное значение, неверно введенный диапазон, отрицательные диапазоны ввода / вывода.
источник
Существует условие, когда все проверяемые значения совпадают, когда код @ jerryjvl возвращает NaN.
источник
Я не выкопал BNF для этого, но документация Arduino имела отличный пример функции, и она разбита. Я смог использовать это в Python, просто добавив переименование def в remap (потому что map является встроенным) и удалив приведение типов и фигурные скобки (то есть просто удалили все 'long').
оригинал
питон
https://www.arduino.cc/en/reference/map
источник
В листинге, представленном PenguinTD, я не понимаю, почему диапазоны меняются местами, он работает без необходимости инвертировать диапазоны. Преобразование линейного диапазона основано на линейном уравнении
Y=Xm+n
, гдеm
иn
получены из заданных диапазонов. Вместо того чтобы ссылаться на диапазоны какmin
иmax
, было бы лучше обозначить их как 1 и 2. Таким образом, формула будет иметь вид:Где,
Y=y1
когдаX=x1
иY=y2
когдаX=x2
.x1
,x2
,y1
&y2
Может быть дано любоеpositive
илиnegative
значение. Определение выражения в макросе делает его более полезным, его можно использовать с любыми именами аргументов.Приведение
float
обеспечило бы деление с плавающей запятой в случае, когда все аргументы являютсяinteger
значениями. В зависимости от применения может не потребоваться проверка диапазоновx1=x2
иy1==y2
.источник
float RangeConv(float input, float x1, float x2, float y1, float y2) { return (((input - x1) * (y2 - y1)) / (x2 - x1)) + y1; }
Вот несколько коротких функций Python для простоты копирования и вставки, включая функцию масштабирования всего списка.
Который можно использовать так:
В моем случае я хотел масштабировать логарифмическую кривую, например так:
источник
Я использовал это решение в проблеме, которую решал в js, поэтому я решил поделиться переводом. Спасибо за объяснение и решение.
источник
C ++ вариант
Я нашел решение PenguinTD полезным, поэтому я перенес его на C ++, если кому-то это нужно:
источник
PHP порт
Решение PenguinTD оказалось полезным, поэтому я перенес его на PHP. Угощайтесь!
источник
Вот версия Javascript, которая возвращает функцию, которая выполняет масштабирование для предварительно определенных диапазонов источника и назначения, сводя к минимуму объем вычислений, который должен выполняться каждый раз.
Вот пример использования этой функции для масштабирования 0-1 в -0x80000000, 0x7FFFFFFF
источник
Сокращенное / упрощенное предложение
уэйн
источник
NewRange/OldRange
здесь?Я лично использую вспомогательный класс, который поддерживает дженерики (Swift 3-совместимый)
источник
В этом примере текущая позиция песни преобразуется в диапазон углов 20-40.
источник
Список понимания одного линейного решения
Более длинная версия
источник
Версия Java
Всегда работает независимо от того, что вы кормите его!
Я оставил все расширенным, чтобы легче было учиться. Округление в конце, конечно, необязательно.
источник