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 года — не изменился. Это и есть смысл фразы «реальный доход»: сравнивать суммы разных лет можно только после того, как их привели к одному году.
Правило простое: любые суммы за разные годы сравнивают только через индекс. Без него сравнение говорит о валюте, а не о жизни.
Карта урока
Скажите своими словами
Не подглядывая, ответьте вслух или на бумаге. Ответы — в конце урока.
- Почему нельзя сложить десять годовых ставок и назвать это ростом цен за десять лет?
- Чем отличаются вопросы «сколько стоит сегодня тысяча 2014 года» и «сколько сегодня нужно вместо тысячи 2014 года»?
- Что значит «зарплата выросла втрое, а в реальных деньгах — в полтора раза»?
Разминка
Три коротких шага перед заданием: предсказать, дописать, починить. Ответы — в конце урока, но сначала ответьте сами.
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 говорит об этом, а не считает молча.
Долги. Индекс сводки построен на годовых ставках Всемирного банка, а они сами — сглаженная годовая оценка. Месячные данные дали бы точнее, и с ними же пришёл бы вопрос про сезонность; оба ждут урока про то, как читать официальную статистику.
Ответы
Показать ответы
На вопросы
- Потому что процент — это множитель, а множители перемножаются. Десять ставок дали множитель 2.42, то есть рост 141.98 %, а их сумма — 92.98 %. Сложение отвечает на вопрос, которого никто не задавал.
- Первый вопрос — про сегодняшнюю тысячу в старых деньгах: 1000 ÷ 2.42 = 413.25. Второй — про старую корзину в сегодняшних деньгах: 1000 × 2.42 = 2419.84. Одно и то же число работает в обе стороны, а ответы отличаются почти в шесть раз.
- Что номинал вырос втрое, но и цены за те же годы выросли: после приведения обеих сумм к деньгам одного года остаётся рост в 1.51 раза. Сравнивать суммы разных лет без индекса — сравнивать разные единицы измерения.
К разминке
- Плюс пятьдесят и минус пятьдесят дают ноль в сумме и 0.75 в произведении: после роста половина считается от большего, а падение — от ещё большего.
сумма процентов: 0 %
множитель: 0.75
от тысячи осталось: 750.0
.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 + 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 %. Обе цифры верны, и только вторая описывает жизнь.
Источники
- Series.cumprod — накопленное произведение, из которого получается индекс.
- Индексы потребительских цен, Бюро национальной статистики РК — официальные индексы Казахстана и их база.
- Инфляция потребительских цен, Всемирный банк — источник ставок этого урока.
Если вы нашли ошибку или опечатку в тексте статьи, то сообщите нам об этом
Комментарии (0)
Войдите, чтобы оставить комментарий →
Пока нет комментариев. Будьте первым.