2015-06-18 3 views
4

У меня есть два значения (предыдущего и текущего), и я хочу, чтобы проверить изменения между ними (в процентах):Как проверить изменение между двумя значениями (в процентах)?

(current/previous)*100 

Но если предыдущее значение 0 я получаю деление на ноль, и если значение не изменится Я получаю 100%.

+4

Если предыдущее значение равно нулю, а текущее значение отличное от нуля, тогда вы не можете означать рассчитывать изменение в пропорции к старому значению; это общий математический принцип, который не имеет ничего общего с программированием. – Hammerite

+0

Если вы хотите, чтобы процент изменения («X% больше»), а не абсолютное сравнение («текущий - X% от предыдущего»), вам нужно сделать '(текущий/предыдущий) * 100 - 100'. Конечно, это все равно не позволит вам делить на ноль. – TigerhawkT3

+0

если 'текущий == предыдущий' не указывает на 0% -ное изменение, а не на 100%? Если он изменяется от 100 до 80, это 20% или 80% в вашем случае использования? – mehtunguh

ответ

6
def get_change(current, previous) 
    if current == previous: 
     return 100.0 
    try: 
     return (abs(current - previous))/previous)*100.0 
    except ZeroDivisionError: 
     return 0 
+0

Если ток равен предыдущему, изменений нет. Вы должны вернуть 0. – Mureinik

+0

Согласно заданному вопросу, «если значение не изменится, я получаю 100%». – Matt

+2

ОП описывал проблему в своем текущем коде, не прося об этом. – Mureinik

4

Вы должны разделить изменение (current-previous) на previous, а не только на текущий. Таким образом, чтобы сделать длинную историю короткой:

change_percent = ((float(current)-previous)/previous)*100 

Обратите внимание, что если previous является 0 вы не можете рассчитать изменение в процентах (независимо от реализации питона)

+0

это не работает со всеми значениями, попробуйте current = 78752 и previous = 39408 Я предполагаю, что это связано с округлением. –

+0

@SvenvandenBoogaart не округляется, но [целое деление] (https://en.wikipedia.org/wiki/Division_ (математика) #Of_integers). Мое редактирование должно решить проблему. – Mureinik

1

Чтобы охватить все случаи нолей, вы могли бы использовать тройные операторы в вашем заявлении

(current - previous)/previous * 100.0 if previous != 0 else float("inf") * abs(current)/current if current != 0 else 0.0 
0

Вы должны разделить по абсолютному значению предыдущего числа. Если предыдущее число отрицательное и текущее число отрицательное, вы получите ошибочный результат, если вы не используете абсолютное значение в знаменателе. Например, если текущий номер -6 ​​и предыдущий номер -5:

(-6 - (-5))/-5 = 

(-6 + 5)/-5 = 

-1/-5 = 20 % 

, который явно ложный, поскольку процентное изменение в этом случае должно быть отрицательным -6 < -5. Поэтому используйте функцию ниже:

def percentage_change(current, previous): 
    if previous != 0 : 
     return float(current - previous)/abs(previous) * 100 
    else: 
     return "undefined" 

Имейте в виду, что если ваше предыдущее число равно нулю, деление на ноль не определено: https://en.wikipedia.org/wiki/Division_by_zero

Также вы не должны использовать абсолютное значение числителе вместо знаменателя , Ниже приведен пример, почему:

предыдущее значение: -5

текущее значение: -4

| (-4 - (-5)) |/-5 = 
| (-4 + 5) |/-5 = 
|1|/-5 = 
1/-5 = -20% 

, который является ложным, поскольку -4 > -5

Правильно:

(-4 - (-5))/| -5 | = 
(-4 + 5)/| -5 | = 
1/5 = 20% 
Смежные вопросы