Shanraq.org Shanraq.org
Инфляция как множитель: сколько стоил тенге
IT

Python: от данных до своей сводки Урок 39 из 56

Инфляция как множитель: сколько стоил тенге

Тридцать восьмой урок курса по Python. Десять годовых ставок, сложенные в сумму, дают 92.98 % — и это неверный ответ: цены выросли на 141.98 %, потому что проценты перемножаются. Индекс через `cumprod`, множитель, среднегодовая ставка и тысяча 2014 года, от которой к 2024-му осталось 413 тенге.

Зачем это нужно

Инфляция объявляется процентом за год, а живут люди годами подряд. Сложить десять процентов в один — первое, что приходит в голову, и это ошибка, которая на десятилетнем ряду ошибается в полтора раза.

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

Сразу целиком

Файл mnozhitel.py. Ставки — из данных Всемирного банка, 2014 год взят за базу.

"""Урок 38: инфляция как множитель — сколько стоил тенге.

Годовые проценты не складываются: они перемножаются. Из ряда ставок собирается
индекс, из индекса — ответ на вопрос, что стало с тысячей.
Источник ставок — Всемирный банк, FP.CPI.TOTL.ZG.
"""

import pandas as pd

# Годовая инфляция Казахстана, проценты. 2014-й — база, поэтому его ставка в
# ряду не нужна: индекс считается от него.
rates = pd.Series(
    [6.68, 14.36, 7.44, 6.16, 5.33, 6.72, 8.04, 15.03, 14.53, 8.69],
    index=[2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024],
    name="ставка",
)

# Каждый год — свой множитель: 6.68 % превращаются в 1.0668.
factors = 1 + rates / 100
# Накопленное произведение и есть индекс цен. База 2014 года = 100.
index = (factors.cumprod() * 100).round(2)
total = factors.prod()

print("== Индекс цен, 2014 = 100")
print(index.to_string())

print()
print("== Во сколько раз выросли цены за десять лет")
print("  множитель:", round(total, 3))
print("  рост:", round((total - 1) * 100, 2), "%")
print("  сумма процентов из ряда:", round(rates.sum(), 2), "% — и она неверна")
print("  разница:", round((total - 1) * 100 - rates.sum(), 2), "процентного пункта")

print()
print("== Что стало с тысячей")
kept = 1000 / total
print("  тысяча тенге в 2024 году имеет такую же покупательную способность, как", round(kept, 2), "тенге в 2014 году")
print("  потеряно:", round(100 - kept / 10, 2), "% покупательной способности")
print("  чтобы купить то же, в 2024 нужно:", round(1000 * total, 2), "тенге")

print()
print("== Какой год считать средним")
geometric = total ** (1 / len(rates)) - 1
print("  среднегодовая по множителям:", round(geometric * 100, 2), "%")
print("  среднее арифметическое ставок:", round(rates.mean(), 2), "%")
print("  за десять лет первое даёт:", round((1 + geometric) ** len(rates), 3))
print("  а второе:", round((1 + rates.mean() / 100) ** len(rates), 3))

print()
print("== Чек 2014 года в ценах каждого года")
basket = 12000
print(" ", basket, "тенге 2014 года — это:")
for year in (2016, 2020, 2024):
    print(f"    {year}: {round(basket * index[year] / 100, 2)} тенге")

print()
print("== Обратный ход: номинал в деньгах 2014 года")
nominal = pd.Series({2016: 15000, 2020: 20000, 2024: 30000}, name="номинал")
real = (nominal / index[nominal.index] * 100).round(2)
print(pd.DataFrame({"номинал": nominal, "в тенге 2014": real}).to_string())

Выводит:

== Индекс цен, 2014 = 100
2015    106.68
2016    122.00
2017    131.08
2018    139.15
2019    146.57
2020    156.42
2021    168.99
2022    194.39
2023    222.64
2024    241.98

== Во сколько раз выросли цены за десять лет
  множитель: 2.42
  рост: 141.98 %
  сумма процентов из ряда: 92.98 % — и она неверна
  разница: 49.0 процентного пункта

== Что стало с тысячей
  тысяча тенге в 2024 году имеет такую же покупательную способность, как 413.25 тенге в 2014 году
  потеряно: 58.67 % покупательной способности
  чтобы купить то же, в 2024 нужно: 2419.84 тенге

== Какой год считать средним
  среднегодовая по множителям: 9.24 %
  среднее арифметическое ставок: 9.3 %
  за десять лет первое даёт: 2.42
  а второе: 2.433

== Чек 2014 года в ценах каждого года
  12000 тенге 2014 года — это:
    2016: 14640.0 тенге
    2020: 18770.4 тенге
    2024: 29037.6 тенге

== Обратный ход: номинал в деньгах 2014 года
      номинал  в тенге 2014
2016    15000      12295.08
2020    20000      12786.09
2024    30000      12397.72

Разбор

Процент — это множитель

6.68 % за год — это умножение на 1.0668. Два года подряд — умножение дважды: 1.0668 × 1.1436, а не сложение. Отсюда всё остальное.

Сложение процентов даёт 92.98 % за десять лет, перемножение — 141.98 %. Разница в 49 процентных пунктов не ошибка округления и не тонкость: это половина ответа.

Индекс — это накопленное произведение

(1 + rates / 100).cumprod() * 100 — весь индекс цен в одной строке. cumprod перемножает нарастающим итогом, поэтому в каждой точке стоит произведение всех предыдущих множителей: 2016-й год — это 122.00, то есть цены к тому году выросли в 1.22 раза от базы.

База — это год, относительно которого считают. У неё нет правильного значения: 100 привычнее, потому что тогда индекс читается как проценты от базы. Важно другое — базу нужно называть. «Индекс 241.98» без слов «2014 = 100» не значит ничего.

Что стало с тысячей

Два вопроса, которые путают, хотя это один множитель:

тысяча тенге в 2024 году имеет такую же покупательную способность, как 413.25 тенге в 2014 году
чтобы купить то же, в 2024 нужно: 2419.84 тенге

Первое — деление на множитель: сколько сегодняшняя тысяча стоит в старых деньгах. Второе — умножение: сколько сегодня нужно за старую корзину. Числа разные (413 и 2420), вопрос разный, а множитель один и тот же.

Потеря покупательной способности считается от первого: 100 % − 41.3 % = 58.7 %. Это и есть цена десяти лет под матрасом.

Средний год — геометрический, а не арифметический

Среднегодовая ставка — это не среднее арифметическое ставок, а такая одна ставка, которая за те же годы даёт тот же множитель:

среднегодовая по множителям: 9.24 %
среднее арифметическое ставок: 9.3 %

Здесь разница мала, но она всегда в одну сторону: арифметическое среднее ставок никогда не меньше геометрического, и за десять лет 9.3 % дают 2.433 вместо настоящих 2.42. Чем сильнее разброс ставок, тем больше расхождение — на ряду с падениями оно становится грубым.

Дефлирование: номинал в деньгах базового года

Обратный ход — разделить номинальную сумму на индекс её года:

      номинал  в тенге 2014
2016    15000      12295.08
2020    20000      12786.09
2024    30000      12397.72

Номинал вырос вдвое, в деньгах 2014 года — не изменился. Это и есть смысл фразы «реальный доход»: сравнивать суммы разных лет можно только после того, как их привели к одному году.

Правило простое: любые суммы за разные годы сравнивают только через индекс. Без него сравнение говорит о валюте, а не о жизни.

Карта урока

Карта урока: ставка, множитель и индекс

Скажите своими словами

Не подглядывая, ответьте вслух или на бумаге. Ответы — в конце урока.

  1. Почему нельзя сложить десять годовых ставок и назвать это ростом цен за десять лет?
  2. Чем отличаются вопросы «сколько стоит сегодня тысяча 2014 года» и «сколько сегодня нужно вместо тысячи 2014 года»?
  3. Что значит «зарплата выросла втрое, а в реальных деньгах — в полтора раза»?

Разминка

Три коротких шага перед заданием: предсказать, дописать, починить. Ответы — в конце урока, но сначала ответьте сами.

1. Предскажите. Что напечатает эта программа?

import pandas as pd

moves = pd.Series([50, -50])
print("сумма процентов:", moves.sum(), "%")
print("множитель:", round((1 + moves / 100).prod(), 3))
print("от тысячи осталось:", round(1000 * (1 + moves / 100).prod(), 2))

2. Заполните пропуск. Вместо ... поставьте то, что превращает ряд множителей в индекс.

# три года по десять процентов
import pandas as pd

rates = pd.Series([10.0, 10.0, 10.0])
index = ((1 + rates / 100)... * 100).round(2)
print(index.to_list())

3. Почините. Программа складывает проценты и объявляет сумму ростом цен.

# три года подряд: 6.68, 14.36 и 7.44 процента
import pandas as pd

rates = pd.Series([6.68, 14.36, 7.44])
print("выросли на", round(rates.sum(), 2), "%")
print("то есть в", round(1 + rates.sum() / 100, 3), "раза")

Задание

Обязательное. Соберите индекс цен Казахстана с 2015 по 2024 год (2014 = 100) и напечатайте: сам индекс, множитель за десять лет, рост в процентах, сумму ставок рядом с пометкой, что так считать нельзя, и среднегодовую ставку. Затем ответьте на два вопроса про тысячу 2014 года. В конце приведите номинальную зарплату трёх лет к деньгам 2014 года и скажите, во сколько раз она выросла в номинале и во сколько — на самом деле.

Ожидаемый вывод:

== Индекс, 2014 = 100
2015    106.68
2016    122.00
2017    131.08
2018    139.15
2019    146.57
2020    156.42
2021    168.99
2022    194.39
2023    222.64
2024    241.98

== Итог десяти лет
  множитель: 2.42
  рост: 141.98 %
  сумма ставок (так считать нельзя): 92.98 %
  среднегодовая: 9.24 %

== Тысяча 2014 года
  покупает столько же, сколько тогда: 413.25 тенге
  чтобы купить прежнее, нужно: 2419.84 тенге

== Зарплата, которая росла втрое
      номинал  в тенге 2014  к 2016 в реальных, %
2016   150000     122950.82                  0.00
2020   250000     159826.11                 29.99
2024   450000     185965.78                 51.25
  номинал вырос в 3.0 раза
  в реальных деньгах — в 1.51 раза

Готово, когда: вывод совпадает построчно; индекс считается cumprod, а не циклом с накоплением; дефлирование — отдельная функция, которой всё равно, что ей дали; ни одна цифра роста не получена сложением процентов.

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

По желанию.

  • Постройте индекс с базой 2020 = 100 и убедитесь, что множитель за 2015–2024 от смены базы не изменился.
  • Посчитайте, за сколько лет цены удваиваются при 9.24 % в год, и сравните с «правилом семидесяти» (70 / ставка).
  • Возьмите ряд с падением цен (отрицательная ставка) и посмотрите, что делает с ним cumprod.

Куда это встанет в проекте

Восемнадцатый шаг: в сводке появляется индекс.

sholu/esep.py получает indeks — по каждой стране собирает из годовых ставок множитель и индекс с базой на первом годе ряда. Страница отчёта показывает их третьим блоком: «во сколько раз выросли цены с 2021 года».

Что получилось на данных сводки: с 2021 по 2025 год цены выросли в 1.595 раза в Казахстане, в 1.462 — в Узбекистане и в 1.42 — в России. Ни одно из этих чисел нельзя получить сложением ставок, и ни одно не равно последней ставке года.

Для сводки это первый расчёт, в котором участвуют все годы сразу, а не последний и предпоследний. Поэтому в нём же появляется первая проверка на разрывы: индекс имеет смысл только для непрерывного ряда лет, и если год пропущен, indeks говорит об этом, а не считает молча.

Долги. Индекс сводки построен на годовых ставках Всемирного банка, а они сами — сглаженная годовая оценка. Месячные данные дали бы точнее, и с ними же пришёл бы вопрос про сезонность; оба ждут урока про то, как читать официальную статистику.

Ответы

Показать ответы

На вопросы

  1. Потому что процент — это множитель, а множители перемножаются. Десять ставок дали множитель 2.42, то есть рост 141.98 %, а их сумма — 92.98 %. Сложение отвечает на вопрос, которого никто не задавал.
  2. Первый вопрос — про сегодняшнюю тысячу в старых деньгах: 1000 ÷ 2.42 = 413.25. Второй — про старую корзину в сегодняшних деньгах: 1000 × 2.42 = 2419.84. Одно и то же число работает в обе стороны, а ответы отличаются почти в шесть раз.
  3. Что номинал вырос втрое, но и цены за те же годы выросли: после приведения обеих сумм к деньгам одного года остаётся рост в 1.51 раза. Сравнивать суммы разных лет без индекса — сравнивать разные единицы измерения.

К разминке

  1. Плюс пятьдесят и минус пятьдесят дают ноль в сумме и 0.75 в произведении: после роста половина считается от большего, а падение — от ещё большего.
сумма процентов: 0 %
множитель: 0.75
от тысячи осталось: 750.0
  1. .cumprod(). Накопленное произведение и есть индекс: 110, 121, 133.1 — а не 110, 120, 130.
import pandas as pd

rates = pd.Series([10.0, 10.0, 10.0])
index = ((1 + rates / 100).cumprod() * 100).round(2)
print(index.to_list())
[110.0, 121.0, 133.1]
  1. Перемножить множители вместо сложения процентов: (1 + rates / 100).prod().
import pandas as pd

rates = pd.Series([6.68, 14.36, 7.44])
print("выросли в", round((1 + rates / 100).prod(), 3), "раза")
print("то есть на", round(((1 + rates / 100).prod() - 1) * 100, 2), "%")
выросли в 1.311 раза
то есть на 31.08 %

К заданию

price_index и deflate вынесены в функции не ради порядка: индекс строят один раз, а приводят к нему потом всё подряд — зарплаты, чеки, тарифы. Функция, которая принимает ряд и индекс и ничего не знает про их смысл, работает со всеми тремя.

Столбец «к 2016 в реальных, %» отвечает на вопрос, ради которого всё считалось: номинал вырос на 200 %, реальные деньги — на 51.25 %. Обе цифры верны, и только вторая описывает жизнь.

Источники

Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом

Проверить задание

Сначала решите и запустите в VS Code — редактор покажет ошибку на месте. Готовое решение вставьте сюда. Проверяет модель: она укажет на ошибку, но не даст готовый ответ.

Чтобы проверить, нужно войти. Войти

Комментарии (0)

Пока нет комментариев. Будьте первым.