В процессе обработки и анализа данных их значения могут преобразовываться. При этом можно оперировать с конкретными элементами или же применять действия одновременно ко всем в столбце или строке. Последний вариант является более предпочтительным в использовании, так как увеличивает производительность при обработке больших объемов данных.
В этом уроке мы познакомимся с методами, которые позволяют уйти от поэлементных операций и применять сценарии обработки ко всему набору данных.
Преобразования данных методом apply()
Метод apply() — это инструмент для преобразования объекта DataFrame. аpply() можно применять как к одному столбцу, так и к нескольким.
Разберем каждую ситуацию подробнее.
apply() для преобразования одного столбца
Рассмотрим пример на данных о кликах на сайте с четырьмя магазинами. Допустим, произошла техническая ошибка, и по первому магазину количество кликов завышено на 50 штук. Исправим это с помощью apply(). Подгрузим данные:
Уменьшим значения продаж для первого магазина на 50 пунктов:
В аргументах apply() находится лямбда-функция языка Python. У нее нет названия, и она используется только в конкретном участке кода. В нашем случае лямбда-функция принимает на вход параметр x и возвращает x - 50. Каждое значение в столбце — это вход указанной функции. Новый столбец формируется из ее выходных значений.
Теперь представим, что появилась дополнительная информация. Количество кликов у магазина 2 завышено на 50 штук, если кликов не более 200, и на 100, если кликов более 200. Попробуем исправить и эту ошибку:
Здесь вместо лямбда-функции в аргументах метода apply() отдельная функция correct_clicks(). Она принимает на вход каждый элемент столбца и выполняет над ним описанное выше преобразование.
Теперь мы узнаем, что у второго столбца порог 200 кликов — это порог между разницей в 50 или 100, у третьего этот порог равен 150 и у четвертого — 250. Выполним параметризацию функции correct_clicks():
В случае параметризации необходимо использовать correct_clicks() в теле лямда-функции.
apply() для преобразования нескольких столбцов
Предположим, что нам необходимо найти наибольшее число кликов за каждый день среди магазинов 1 и 3. Сформируем новый столбец MAX_SHOP1_SHOP3:
В первых двух строчках мы заполнили пропуски в данных средними значениями с помощью метода fillna(). Это нужно, чтобы не было ошибок при вызове функции max(). Далее apply() применяется ко всему DataFrame. Параметр axis задает направление обхода набора данных:
- 0 задает обход по столбцам
- 1 задает обход по строкам
Мы использовали значение 1, так в качестве аргумента x лямбда-функции выступают строки набора данных. Так как мы ищем максимум среди 1 и 3 магазинов, то обращаемся к соответствующим значениям по ключам магазинов: SHOP1 и SHOP3.
Теперь учтем следующую информацию: если максимум окажется больше, чем 200, то мы должны заполнить столбец числом -1. Это будет говорить о некоторой технической ошибке:
Векторизованные функции
В отличие от метода apply() векторизованные функции преобразовывают столбцы не поэлементно, а целыми списками. Это позволяет выполнять вычисления быстрее. Найдем сумму кликов двух магазинов с помощью разных подходов, и сравним скорость их выполнения:
Разница в производительности больше в два раза. Векторизованные функции более производительны. Но функционал векторизованных функций ограничен. При этом с помощью метода apply() можно выполнять сложные преобразования.
Векторные арифметические операции
Над столбцами можно выполнять основные арифметические операции. Выше был пример операции сложений. Ниже случаи для других операций:
Из примеров видно, что арифметические операции можно выполнять как между столбцами, так и между столбцом и другим объектом, например, числом. Этот прием называется укладыванием. Он также позволяет выполнять операции быстрее, чем проход по элементам в цикле.
Изменение типов данных
Тип столбцов важен для DataFrame. От него зависит корректность проведения тех или иных операций. Иногда его приходится изменять.
Предположим, что нам в каких-то целях необходимо поработать с числовым столбцом, как со строковыми данными. Это можно легко сделать с помощью метода astype():
Преобразуем тип для SHOP1:
Метод astype() ожидает на вход тип объекта, к которому необходимо привести элементы столбца.
Замена элементов согласно словарю
Существуют преобразования данных в столбцах DataFrame, которые требуют заменить одно значение на другое. Если подстановку значений можно задать с помощью словаря, то достаточно воспользоваться методом map().
Допустим, 150 кликов и более — это хорошо, а меньше — это плохо. Добавим столбец с категорией значений 0 и 1 согласно данному условию:
Создадим словарь, согласно которому будет выполняться замена:
Заменим значения столбца GOOD_OR_BAD:
Выводы
В этом уроке мы познакомились с несколькими способами преобразования строк и столбцов объекта DataFrame библиотеки Pandas.
Обычно выделяют два подхода:
- Использование метода apply()
- Применение векторизованных функций
В случае использования метода apply() можно выполнять сложное преобразование, но вычисления будут сравнительно долгими. В случае векторизованных функций все наоборот — получаем высокую производительность, но ограниченный функционал. Обычно аналитики делают свой выбор в зависимости от условий задачи.
<!DOCTYPE html>
<html class="h-100" data-bs-theme="light" data-mantine-color-scheme="light" lang="ru" prefix="og: https://ogp.me/ns#">
<head>
<meta content="width=device-width, initial-scale=1.0" name="viewport">
<meta content="IE=Edge" http-equiv="X-UA-Compatible">
<link crossorigin="true" href="https://cdn.hexlet.io" rel="preconnect">
<link href="https://mc.yandex.ru" rel="preconnect">
<meta content="aa2vrdtq64dub8knuf83lwywit311w" name="facebook-domain-verification">
<link href="/favicon.ico" rel="icon" sizes="any">
<link href="/favicon.svg" rel="icon" type="image/svg+xml">
<link href="/apple-touch-icon.png" rel="apple-touch-icon">
<link href="/manifest.webmanifest" rel="manifest">
<script>
//<![CDATA[
window.gon={};gon.ym_counter="25559621";gon.is_bot=true;gon.applications={};gon.current_user={"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26 19:53:16 UTC","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false};gon.token="VnBuFsgqmUO-Q8Vh3vZtcX67-8OTjI2wLSKXDMuDxXq5oaUhOlQ0IwgA4fnS-Z0GvrLWaZu7cxKQwg1YmYQiFA";gon.locale="ru";gon.language="ru";gon.theme="light";gon.rails_env="production";gon.mobile=false;gon.google={"analytics_key":"UA-1360700-51","optimize_key":"GTM-5QDVFPF"};gon.captcha={"google_v3_site_key":"6LenGbgZAAAAAM7HbrDbn5JlizCSzPcS767c9vaY","yandex_site_key":"ysc1_Vyob5ZPPUdPBsu0ykt8bVFdzsfpoVjQChLGl2b4g19647a89","verification_failed":null};gon.social_signin=false;gon.typoreporter_google_form_id="1FAIpQLSeibfGq-KvWQ2Fyru-zkFFRVTLBuzXAHAoEyN1p49FtDmNoNA";
//]]>
</script>
<meta charset="utf-8">
<title>Применение функций к столбцам и строкам таблицы | Python: Pandas</title>
<meta name="description" content="Применение функций к столбцам и строкам таблицы / Python: Pandas: Разберем уход от поэлементных операций с данными — применение векторизованных функций для ускорения операций над строками и столбцами">
<link rel="canonical" href="https://ru.hexlet.io/courses/python-pandas/lessons/pandas-column-functions/theory_unit">
<meta name="robots" content="noarchive">
<meta property="og:title" content="Применение функций к столбцам и строкам таблицы">
<meta property="og:title" content="Python: Pandas">
<meta property="og:description" content="Применение функций к столбцам и строкам таблицы / Python: Pandas: Разберем уход от поэлементных операций с данными — применение векторизованных функций для ускорения операций над строками и столбцами">
<meta property="og:url" content="https://ru.hexlet.io/courses/python-pandas/lessons/pandas-column-functions/theory_unit">
<meta name="csrf-param" content="authenticity_token" />
<meta name="csrf-token" content="uI9Lb184QcXRfFYO6eBfjUJ6XJo7z1yUgfhIrDEs3WNXXoBYrUbspWc_cpbl76_6gnNxMDP4ojY8GNL4Yys6DQ" />
<script src="/vite/assets/inertia-DfXos102.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/preload-helper-BJ4cLWpC.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-BrRXra1y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ahoy-DrlRQ-1D.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/analytics-cb8xch9l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Surface-DL2bpZA-.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/extends-C-EagtpE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/inheritsLoose-BBd-DCVI.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/objectWithoutPropertiesLoose-DRHXDhjp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/index.esm-DAqKOkZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Button-CGPUux8l.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/CloseButton-D1euiPao.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Group-BX48WcuU.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Loader-BQEY8g6v.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Modal-Cy3HByv7.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/OptionalPortal-1Hza5P2w.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Stack-CtjJzfw4.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Textarea-Ck64llAy.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/DirectionProvider-Dc9zdUke.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/events-DJQOhap0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-reduced-motion-D2owz4wa.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-disclosure-zKtK5W1r.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/use-hotkeys-Cnc_Rwkb.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/random-id-DOQyszCZ.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/exports-C_MrNx_T.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<link rel="stylesheet" href="/vite/assets/application-BqhCP46M.js" />
<script src="/vite/assets/application-Df9RExpe.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/autocomplete-VMNbxKGl.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/createPopper-C3aM9r1M.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/js.cookie-D1-O8zkX.js" as="script" crossorigin="anonymous"><link rel="stylesheet" href="/vite/assets/application-C8HjmMaq.css" media="screen" />
<script>
window.ym = function(){(ym.a=ym.a||[]).push(arguments)};
window.addEventListener('load', function() {
setTimeout(function() {
ym.l = 1*new Date();
ym(window.gon.ym_counter, "init", {
clickmap: true,
trackLinks: true,
accurateTrackBounce: true,
webvisor: true
});
// Загружаем скрипт
var k = document.createElement('script');
k.async = 1;
k.src = 'https://mc.yandex.ru/metrika/tag.js';
document.head.appendChild(k);
ym(window.gon.ym_counter, 'getClientID', function(clientID) {
window.ymClientId = clientID;
});
}, 1500);
});
</script>
<!-- Google Tag Manager - deferred -->
<script>
// dataLayer stub сразу — пуши работают до загрузки скрипта
window.dataLayer = window.dataLayer || [];
// Сам скрипт — отложенно после load
window.addEventListener('load', function() {
setTimeout(function() {
dataLayer.push({'gtm.start': new Date().getTime(), event: 'gtm.js'});
var j = document.createElement('script');
j.async = true;
j.src = 'https://www.googletagmanager.com/gtm.js?id=GTM-WK88TH';
document.head.appendChild(j);
}, 1500);
});
</script>
<!-- End Google Tag Manager -->
</head>
<body>
<noscript>
<div>
<img alt="" src="https://mc.yandex.ru/watch/25559621" style="position:absolute; left:-9999px;">
</div>
</noscript>
<header class="sticky-top bg-body">
<nav class="navbar navbar-expand-lg">
<div class="container-xxl">
<a class="navbar-brand" href="/"><img alt="Логотип Хекслета" height="24" src="https://ru.hexlet.io/vite/assets/logo_ru_light-BpiEA1LT.svg" width="96">
</a><button aria-controls="collapsable" aria-expanded="false" aria-label="Меню" class="navbar-toggler border-0 mb-0 mt-1" data-bs-target="#collapsable" data-bs-toggle="collapse">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="collapsable">
<ul class="navbar-nav mb-lg-0 mt-lg-1">
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
Все курсы
<span class="bi bi-chevron-down align-middle ms-1"></span>
</button>
<ul class="dropdown-menu">
<li>
<a class="dropdown-item d-flex py-2" href="/courses"><div class="fw-bold me-auto">Все что есть</div>
<div class="text-muted">117</div>
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные категории</b>
</li>
<li>
<a class="dropdown-item py-2" href="/courses_devops">Курсы по DevOps
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_data_analytics">Курсы по аналитике данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_programming">Курсы по программированию
</a></li>
<li>
<a class="dropdown-item py-2" href="/courses_testing">Курсы по тестированию
</a></li>
<li>
<hr class="dropdown-divider">
</li>
<li class="dropdown-item">
<b>Популярные курсы</b>
</li>
<li>
<a class="dropdown-item py-2" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/go">Go-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/java">Java-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/python">Python-разработчик
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/qa-auto-engineer-java">Автоматизатор тестирования на Java
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/data-analytics">Аналитик данных
</a></li>
<li>
<a class="dropdown-item py-2" href="/programs/frontend">Фронтенд-разработчик
</a></li>
</ul>
</li>
<li class="nav-item dropdown">
<button aria-haspopup class="btn nav-link" data-bs-toggle="dropdown" type="button">
О Хекслете
<span class="bi bi-chevron-down align-middle"></span>
</button>
<ul class="dropdown-menu bg-body">
<li>
<a class="dropdown-item py-2" href="/pages/about">О нас
</a></li>
<li>
<a class="dropdown-item py-2" href="/blog">Блог
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/hse-research" role="button">Результаты (Исследование)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://career.hexlet.io" role="button">Хекслет Карьера
</span></li>
<li>
<a class="dropdown-item py-2" href="/testimonials">Отзывы студентов
</a></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://t.me/hexlet_help_bot" role="button">Поддержка (В ТГ)
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/referal-program/?promo_creative=priglasite-druzei&promo_name=referal-program&promo_position=promo_position&promo_start=010724&promo_type=link" role="button">Реферальная программа
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://special.hexlet.io/certificate" role="button">Подарочные сертификаты
</span></li>
<li>
<span class="dropdown-item py-2 external-link" data-href="https://hh.ru/employer/4307094" role="button">Вакансии
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://b2b.hexlet.io" data-target="_blank" role="button">Компаниям
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexly.ru/" data-target="_blank" role="button">Колледж
</span></li>
<li>
<span class="dropdown-item d-flex external-link" rel="noopener noreferrer nofollow" data-href="https://hexlyschool.ru/" data-target="_blank" role="button">Частная школа
</span></li>
</ul>
</li>
<li><a class="nav-link" href="/subscription/new">Подписка</a></li>
</ul>
<ul class="navbar-nav flex-lg-row align-items-lg-center gap-2 ms-auto">
<li>
<a class="nav-link" aria-label="Переключить тему" href="/theme/switch?new_theme=dark"><span aria-hidden="true" class="bi bi-moon"></span>
</a></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="/u/new" role="button"><span>Регистрация</span>
</span></li>
<li>
<span data-target="_self" class="nav-link external-link" data-href="https://ru.hexlet.io/session/new" role="button"><span>Вход</span>
</span></li>
</ul>
</div>
</div>
</nav>
</header>
<div class="x-container-xxxl">
</div>
<main class="mb-6 min-vh-100 h-100">
<link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzY1MywicHVyIjoiYmxvYl9pZCJ9fQ==--5107185de77b3481e0a836f9fc7326c4e1b77be4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Data%20extraction-pana.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk1OSwicHVyIjoiYmxvYl9pZCJ9fQ==--39f076671bc03debdf48e861bbd4c34c3fd4aac8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Data%20extraction-bro.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDg3MSwicHVyIjoiYmxvYl9pZCJ9fQ==--8175585f43b5401994e29b3ae73d76963d942512/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Browser%20stats-bro.png"/><link rel="preload" as="image" href="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDg2MiwicHVyIjoiYmxvYl9pZCJ9fQ==--04a703ca18d7bf689064f1f3c2721058bd5564e4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Statistics-bro.png"/><link rel="preload" as="image" href="/vite/assets/development-BVihs_d5.png"/><div id="app" data-page="{"component":"web/courses/lessons/theory_unit","props":{"errors":{},"locale":"ru","language":"ru","httpsHost":"https://ru.hexlet.io","host":"ru.hexlet.io","colorScheme":"light","auth":{"user":{"id":null,"last_viewed_notification_id":null,"email":null,"state":null,"first_name":"","last_name":"","created_at":"2026-02-26T19:53:15.885Z","current_program":null,"current_team":null,"full_name":"","guest":true,"can_use_paid_features":false,"is_hexlet_employee":false,"sanitized_phone_number":"","can_subscribe":true,"can_renew_education":false}},"cloudflareTurnstileSiteKey":"0x4AAAAAAA15KmeFXzd2H0Xo","vkIdClientId":"51586979","yandexIdClientId":"88d071f1d3384eb4bd1deb37910235c7","formAuthToken":"rW9Hcc9cDV_f0WosT_BK9aNb6JjBBky5_5Zo3vzLM25CvoxGPSKgP2mSTrRD_7qCY1LFMskxshtCdvKKrszUAA","topics":[{"id":91193,"title":"1. Названия столбцов в примерах задания shop_1, shop_2 и т.д. А в решении нужно использовать SHOP1, SHOP2 и т.д. Возможно, следует исправить формулировку задания?\n\n2. Странно, но задание №2 принимает даже есть написать функцию для другого столбца, а не SHOP1, как требуется. Принятое решение для столбца SHOP4:\nhttps://ru.hexlet.io/code_reviews/1107158","plain_title":"Названия столбцов в примерах задания shop1, shop2 и т.д. А в решении нужно использовать SHOP1, SHOP2 и т.д. Возможно, следует исправить формулировку задания? Странно, но задание №2 принимает даже есть написать функцию для другого столбца, а не SHOP1, как требуется. Принятое решение для столбца SHOP4: https://ru.hexlet.io/code_reviews/1107158 ","creator":{"public_name":"","id":320505,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Mamtsev","id":294764,"is_tutor":true},"id":180771,"body":"Добрый день, спасибо за замечения. Поправлю и формулировку и тесты.","topic_id":91193}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Применение функций к столбцам и строкам таблицы","entity_url":null,"active":true}},{"id":94515,"title":"В данных по SHOP1, присутствуют nan значения. Нигде в задании не сказано, что их нужно исправлять + оракул с данными считает эти позиции как >=200 (ожидает 1 и good)","plain_title":"В данных по SHOP1, присутствуют nan значения. Нигде в задании не сказано, что их нужно исправлять + оракул с данными считает эти позиции как >=200 (ожидает 1 и good) ","creator":{"public_name":"Евгений Баженов","id":145691,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Mamtsev","id":294764,"is_tutor":true},"id":185228,"body":"Добрый день, спасибо за замечание. Поправлю описание, что нужно заменить NaN на среднее.","topic_id":94515}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Применение функций к столбцам и строкам таблицы","entity_url":null,"active":true}},{"id":98986,"title":"Блок \"Изменение типов данных\". Небольшая опечатка в коде, ~~d~~df_clicks.\n```\ndf_clicks['SHOP1'] = df_clicks['SHOP1'].astype(str)\nprint(ddf_clicks[['SHOP1', 'SHOP2']].info())\n```\n","plain_title":"Блок \"Изменение типов данных\". Небольшая опечатка в коде, ~~d~~dfclicks. ``` dfclicks['SHOP1'] = dfclicks['SHOP1'].astype(str) print(ddfclicks[['SHOP1', 'SHOP2']].info()) ``` ","creator":{"public_name":"Andrey Volkov","id":662030,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Gagarinov","id":75907,"is_tutor":true},"id":190352,"body":"**Andrey Volkov**, спасибо! Поправил.","topic_id":98986}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Применение функций к столбцам и строкам таблицы","entity_url":null,"active":true}},{"id":104386,"title":"в описании первой функции написано, что должен измениться только столбец 'SHOP1', а в примере меняются все столбцы","plain_title":"в описании первой функции написано, что должен измениться только столбец 'SHOP1', а в примере меняются все столбцы ","creator":{"public_name":"Анна Краснова","id":726689,"is_tutor":false},"comments":[{"creator":{"public_name":"Ivan Mamtsev","id":294764,"is_tutor":true},"id":196962,"body":"Поправил, спасибо","topic_id":104386}],"communitable":{"parent_entity_name":null,"parent_entity_url":null,"entity_name":"Применение функций к столбцам и строкам таблицы","entity_url":null,"active":true}}],"lesson":{"exercise":{"id":2336,"slug":"python-pandas-pandas-column-functions-exercise","name":null,"state":"active","kind":"exercise","language":"python","locale":"ru","has_web_view":false,"has_test_view":false,"reviewable":true,"readme":"## solution.py\n\n1. Аналитики заметили, что значения сохранены в формате `float`. Количество кликов — это целое число. Реализуйте функцию `change_type`, которая принимает в качестве аргумента `DataFrame` и изменяет формат столбца `SHOP1` с `float` на `int`.\n\n ```python\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4\n # 0 1 319.0 -265.0 319.0 328.0\n # 1 2 292.0 274.0 292.0 301.0\n\n test_df = change_type(test_df)\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4\n # 0 1 319 -265.0 319.0 328.0\n # 1 2 292 274.0 292.0 301.0\n ```\n\n2. Количество кликов, которое равно или более 200, считается хорошим показателем. Реализуйте функцию `get_clicks_statistic`, которая принимает в качестве аргумента `DataFrame` и формирует для первого магазина новый столбец с названием `CLICKS_STATISTIC` по следующему правилу: если кликов равно или более 200, то в новом столбце будет значение `1`, если менее — `0`.\n\n ```python\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4\n # 0 1 319.0 -265.0 319.0 328.0\n # 1 2 50.0 190.0 113.0 42.0\n\n test_df = get_clicks_statistic(test_df)\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4 CLICKS_STATISTIC\n # 0 1 319.0 -265.0 319.0 328.0 1\n # 1 2 50.0 190.0 113.0 42.0 0\n ```\n\n3. Для передачи статистики в другой отдел необходимо заменить значения в столбце `CLICKS_STATISTIC`. Реализуйте функцию `change_statistic`, которая принимает в качестве аргумента `DataFrame` и изменяет значение `0` на слово `bad`, значение `1` — на слово `good`.\n\n ```python\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4 CLICKS_STATISTIC\n # 0 1 319.0 -265.0 319.0 328.0 1\n # 1 2 50.0 190.0 113.0 42.0 0\n\n test_df = change_statistic(test_df)\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4 CLICKS_STATISTIC\n # 0 1 319.0 -265.0 319.0 328.0 good\n # 1 2 50.0 190.0 113.0 42.0 bad\n ```\n\n\n### Подсказки\n\n* В исходных данных могут встречаться `NaN` значения. Замените их на среднее (`mean`)\n","prepared_readme":"## solution.py\n\n1. Аналитики заметили, что значения сохранены в формате `float`. Количество кликов — это целое число. Реализуйте функцию `change_type`, которая принимает в качестве аргумента `DataFrame` и изменяет формат столбца `SHOP1` с `float` на `int`.\n\n ```python\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4\n # 0 1 319.0 -265.0 319.0 328.0\n # 1 2 292.0 274.0 292.0 301.0\n\n test_df = change_type(test_df)\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4\n # 0 1 319 -265.0 319.0 328.0\n # 1 2 292 274.0 292.0 301.0\n ```\n\n2. Количество кликов, которое равно или более 200, считается хорошим показателем. Реализуйте функцию `get_clicks_statistic`, которая принимает в качестве аргумента `DataFrame` и формирует для первого магазина новый столбец с названием `CLICKS_STATISTIC` по следующему правилу: если кликов равно или более 200, то в новом столбце будет значение `1`, если менее — `0`.\n\n ```python\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4\n # 0 1 319.0 -265.0 319.0 328.0\n # 1 2 50.0 190.0 113.0 42.0\n\n test_df = get_clicks_statistic(test_df)\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4 CLICKS_STATISTIC\n # 0 1 319.0 -265.0 319.0 328.0 1\n # 1 2 50.0 190.0 113.0 42.0 0\n ```\n\n3. Для передачи статистики в другой отдел необходимо заменить значения в столбце `CLICKS_STATISTIC`. Реализуйте функцию `change_statistic`, которая принимает в качестве аргумента `DataFrame` и изменяет значение `0` на слово `bad`, значение `1` — на слово `good`.\n\n ```python\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4 CLICKS_STATISTIC\n # 0 1 319.0 -265.0 319.0 328.0 1\n # 1 2 50.0 190.0 113.0 42.0 0\n\n test_df = change_statistic(test_df)\n print(test_df)\n # => day SHOP1 SHOP2 SHOP3 SHOP4 CLICKS_STATISTIC\n # 0 1 319.0 -265.0 319.0 328.0 good\n # 1 2 50.0 190.0 113.0 42.0 bad\n ```\n\n\n### Подсказки\n\n* В исходных данных могут встречаться `NaN` значения. Замените их на среднее (`mean`)\n","has_solution":true,"entity_name":"Применение функций к столбцам и строкам таблицы"},"units":[{"id":7573,"name":"theory","url":"/courses/python-pandas/lessons/pandas-column-functions/theory_unit"},{"id":7574,"name":"quiz","url":"/courses/python-pandas/lessons/pandas-column-functions/quiz_unit"},{"id":8016,"name":"exercise","url":"/courses/python-pandas/lessons/pandas-column-functions/exercise_unit"}],"links":[{"id":424141,"name":"pandas.DataFrame.apply()","url":"https://pandas.pydata.org/docs/reference/api/pandas.DataFrame.apply.html"},{"id":424142,"name":"Руководство по векторизованным операциям","url":"https://pandas.pydata.org/docs/user_guide/basics.html#array-operations"},{"id":424143,"name":"pandas.Series.map()","url":"https://pandas.pydata.org/docs/reference/api/pandas.Series.map.html"}],"ordered_units":[{"id":7573,"name":"theory","url":"/courses/python-pandas/lessons/pandas-column-functions/theory_unit"},{"id":7574,"name":"quiz","url":"/courses/python-pandas/lessons/pandas-column-functions/quiz_unit"},{"id":8016,"name":"exercise","url":"/courses/python-pandas/lessons/pandas-column-functions/exercise_unit"}],"id":3369,"slug":"pandas-column-functions","state":"approved","name":"Применение функций к столбцам и строкам таблицы","course_order":160,"goal":"Разберем уход от поэлементных операций с данными — применение векторизованных функций для ускорения операций над строками и столбцами","self_study":"Склонируйте [репозиторий](https://github.com/hexlet-components/data-datasets) и возьмите `data/Cite_clicks.csv`. Повторите преобразования из урока, чтобы закрепить `apply()`, векторные операции и работу с типами.\n\n**Подготовка**\n\n1. Загрузите данные (`index_col=0`), выведите `head()` и убедитесь, что типы столбцов числовые.\n2. Создайте копию датафрейма, чтобы экспериментировать, не затрагивая оригинал.\n\n**Одностолбцовые преобразования**\n\n1. Используя `apply()` с `lambda`, уменьшите значения `SHOP1` на 50.\n2. Реализуйте функцию `correct_clicks(x)` с условной логикой (разные пороги), примените ее к `SHOP2`.\n3. Параметризуйте ту же функцию (аргумент `threshold`) и обработайте `SHOP3` и `SHOP4`.\n\n**Построчные вычисления**\n\n1. Заполните пропуски в `SHOP1`/`SHOP3` средними значениями (`fillna`).\n2. Добавьте столбец `MAX_SHOP1_SHOP3` через `df.apply(..., axis=1)` и функцию `max`.\n3. Напишите функцию, которая возвращает `-1`, если максимум > 200, иначе — сам максимум; создайте столбец `MAX_SHOP1_SHOP3_CORRECT`.\n\n**Векторные операции**\n\n1. Посчитайте сумму `SHOP1 + SHOP2` двумя способами: через `apply` и векторно; замерьте время (`%time` в ноутбуке или `timeit`).\n2. Добавьте столбцы с умножением и вычитанием (`df['SHOP1'] * df['SHOP2']`, `df['SHOP1'] - 100`) и сравните с ручными циклами (для понимания разницы).\n\n**Типы данных и замены**\n\n1. Приведите `SHOP1` к строковому типу с `astype(str)` и проверьте `df.info()`.\n2. Создайте бинарный столбец `GOOD_OR_BAD` (0/1) на основе порога для `SHOP2`, затем замените значения через `map({0: 'BAD', 1: 'GOOD'})`.\n\n**Контроль**\n\n- Все шаги из урока воспроизведены: функции `apply`, векторные операции, `astype`, `map`.\n- В коде отмечено, чем `apply` отличается от векторных операций по скорости.\n- Итоговый датафрейм содержит новые столбцы (`MAX_*`, `SUM`, `GOOD_OR_BAD`) и не ломает исходные данные.\n","theory_video_provider":null,"theory_video_uid":null,"theory":"В процессе обработки и анализа данных их значения могут преобразовываться. При этом можно оперировать с конкретными элементами или же применять действия одновременно ко всем в столбце или строке. Последний вариант является более предпочтительным в использовании, так как увеличивает производительность при обработке больших объемов данных.\n\nВ этом уроке мы познакомимся с методами, которые позволяют уйти от поэлементных операций и применять сценарии обработки ко всему набору данных.\n\n## Преобразования данных методом apply()\n\nМетод `apply()` — это инструмент для преобразования объекта `DataFrame`. `аpply()` можно применять как к одному столбцу, так и к нескольким.\n\nРазберем каждую ситуацию подробнее.\n\n### apply() для преобразования одного столбца\n\nРассмотрим пример на данных о кликах на сайте с четырьмя магазинами. Допустим, произошла техническая ошибка, и по первому магазину количество кликов завышено на 50 штук. Исправим это с помощью `apply()`. Подгрузим данные:\n\n```python\nimport pandas as pd\n\ndf_clicks = pd.read_csv('./data/Cite_clicks.csv', index_col=0)\nprint(df_clicks.head())\n# => SHOP1\tSHOP2\tSHOP3\tSHOP4\n# day\n# 1\t319.0\t-265.0\t319.0\t328.0\n# 2\t292.0\t274.0\t292.0\t301.0\n# 3\t283.0\t301.0\t274.0\t283.0\n# 4\t328.0\t364.0\t328.0\tNaN\n# 5\t391.0\t355.0\t373.0\t337.0\n```\n\nУменьшим значения продаж для первого магазина на 50 пунктов:\n\n```python\ndf_clicks['SHOP1'] = df_clicks['SHOP1'].apply(lambda x: x - 50)\nprint(df_clicks.head())\n# => SHOP1\tSHOP2\tSHOP3\tSHOP4\n# day\n# 1\t 269.0\t-265.0\t319.0\t328.0\n# 2\t 242.0\t274.0\t292.0\t301.0\n# 3\t 233.0\t301.0\t274.0\t283.0\n# 4\t 278.0\t364.0\t328.0\tNaN\n# 5\t 341.0\t355.0\t373.0\t337.0\n```\n\nВ аргументах `apply()` находится лямбда-функция языка Python. У нее нет названия, и она используется только в конкретном участке кода. В нашем случае лямбда-функция принимает на вход параметр `x` и возвращает `x - 50`. Каждое значение в столбце — это вход указанной функции. Новый столбец формируется из ее выходных значений.\n\nТеперь представим, что появилась дополнительная информация. Количество кликов у магазина 2 завышено на 50 штук, если кликов не более 200, и на 100, если кликов более 200. Попробуем исправить и эту ошибку:\n\n```python\ndef correct_clicks(x):\n if x < 200:\n return x - 50\n else:\n return x - 100\n\ndf_clicks['SHOP2'] = df_clicks['SHOP2'].apply(correct_clicks)\nprint(df_clicks.head())\n# => \tSHOP1\tSHOP2\tSHOP3\tSHOP4\n# day\n# 1\t269.0\t-315.0\t319.0\t328.0\n# 2\t242.0\t174.0\t292.0\t301.0\n# 3\t233.0\t201.0\t274.0\t283.0\n# 4\t278.0\t264.0\t328.0\tNaN\n# 5\t341.0\t255.0\t373.0\t337.0\n```\n\nЗдесь вместо лямбда-функции в аргументах метода `apply()` отдельная функция `correct_clicks()`. Она принимает на вход каждый элемент столбца и выполняет над ним описанное выше преобразование.\n\nТеперь мы узнаем, что у второго столбца порог 200 кликов — это порог между разницей в 50 или 100, у третьего этот порог равен 150 и у четвертого — 250. Выполним параметризацию функции `correct_clicks()`:\n\n```python\ndef correct_clicks(x, threshold):\n if x < threshold:\n return x - 50\n else:\n return x - 100\n\ndf_clicks['SHOP3'] = df_clicks['SHOP3'].apply(lambda x: correct_clicks(x, 150))\ndf_clicks['SHOP4'] = df_clicks['SHOP4'].apply(lambda x: correct_clicks(x, 250))\n\nprint(df_clicks.head())\n# => SHOP1\tSHOP2\tSHOP3\tSHOP4\n# day\n# 1\t269.0\t-315.0\t169.0\t328.0\n# 2\t242.0\t174.0\t142.0\t301.0\n# 3\t233.0\t201.0\t124.0\t283.0\n# 4\t278.0\t264.0\t178.0\tNaN\n# 5\t341.0\t255.0\t173.0\t337.0\n```\n\nВ случае параметризации необходимо использовать `correct_clicks()` в теле лямда-функции.\n\n### apply() для преобразования нескольких столбцов\n\nПредположим, что нам необходимо найти наибольшее число кликов за каждый день среди магазинов 1 и 3. Сформируем новый столбец `MAX_SHOP1_SHOP3`:\n\n```python\ndf_clicks['SHOP1'] = df_clicks['SHOP1'].fillna(df_clicks['SHOP1'].mean())\ndf_clicks['SHOP3'] = df_clicks['SHOP3'].fillna(df_clicks['SHOP3'].mean())\n\ndf_clicks['MAX_SHOP1_SHOP3'] = df_clicks.apply(lambda x: max(x['SHOP1'], x['SHOP3']), axis=1)\nprint(df_clicks.head())\n# => SHOP1\tSHOP2\tSHOP3\tSHOP4\tMAX_SHOP1_SHOP3\n# day\n# 1\t269.0\t-315.0\t169.0\t328.0\t 269.0\n# 2\t242.0\t174.0\t142.0\t301.0\t 242.0\n# 3\t233.0\t201.0\t124.0\t283.0\t 233.0\n# 4\t278.0\t264.0\t178.0\tNaN\t 278.0\n# 5\t341.0\t255.0\t173.0\t337.0\t 341.0\n```\n\nВ первых двух строчках мы заполнили пропуски в данных средними значениями с помощью метода `fillna()`. Это нужно, чтобы не было ошибок при вызове функции `max()`. Далее `apply()` применяется ко всему `DataFrame`. Параметр `axis` задает направление обхода набора данных:\n\n* 0 задает обход по столбцам\n* 1 задает обход по строкам\n\nМы использовали значение 1, так в качестве аргумента `x` лямбда-функции выступают строки набора данных. Так как мы ищем максимум среди 1 и 3 магазинов, то обращаемся к соответствующим значениям по ключам магазинов: `SHOP1` и `SHOP3`.\n\nТеперь учтем следующую информацию: если максимум окажется больше, чем 200, то мы должны заполнить столбец числом -1. Это будет говорить о некоторой технической ошибке:\n\n```python\ndef correct_max(x, threshold):\n if max(x['SHOP1'], x['SHOP3']) > threshold:\n return -1\n return max(x['SHOP1'], x['SHOP3'])\n\ndf_clicks['MAX_SHOP1_SHOP3_CORRECT'] = df_clicks.apply(lambda x: correct_max(x, 200), axis=1)\nprint(df_clicks.head())\n# =>\tSHOP1\tSHOP2\tSHOP3\tSHOP4\tMAX_SHOP1_SHOP3\tMAX_SHOP1_SHOP3_CORRECT\n# day\n# 1\t269.0\t-315.0\t169.0\t328.0\t 269.0\t -1.0\n# 2\t242.0\t174.0\t142.0\t301.0\t 242.0\t -1.0\n# 3\t233.0\t201.0\t124.0\t283.0\t 233.0\t -1.0\n# 4\t278.0\t264.0\t178.0\tNaN\t 278.0\t -1.0\n# 5\t341.0\t255.0\t173.0\t337.0\t 341.0\t -1.0\n```\n\n## Векторизованные функции\n\nВ отличие от метода `apply()` векторизованные функции преобразовывают столбцы не поэлементно, а целыми списками. Это позволяет выполнять вычисления быстрее. Найдем сумму кликов двух магазинов с помощью разных подходов, и сравним скорость их выполнения:\n\n```python\n%time df_clicks['SUM'] = df_clicks.apply(lambda x: x['SHOP1'] + x['SHOP2'], axis=1)\n# => CPU times: user 1.11 ms, sys: 57 µs, total: 1.17 ms\n# Wall time: 1.15 ms\n```\n\n```python\n%time df_clicks['SUM'] = df_clicks['SHOP1'] + df_clicks['SHOP2']\n# => CPU times: user 541 µs, sys: 16 µs, total: 557 µs\n# Wall time: 526 µs\n```\n\nРазница в производительности больше в два раза. Векторизованные функции более производительны. Но функционал векторизованных функций ограничен. При этом с помощью метода `apply()` можно выполнять сложные преобразования.\n\n### Векторные арифметические операции\n\nНад столбцами можно выполнять основные арифметические операции. Выше был пример операции сложений. Ниже случаи для других операций:\n\n```python\ndf_clicks['MULTIPLE'] = df_clicks['SHOP1'] * df_clicks['SHOP2']\nprint(df_clicks[['SHOP1', 'SHOP2', 'MULTIPLE']].head())\n# => \tSHOP1\tSHOP2\tMULTIPLE\n# day\n# 1\t319.0\t-265.0\t-84535.0\n# 2\t292.0\t274.0\t80008.0\n# 3\t283.0\t301.0\t85183.0\n# 4\t328.0\t364.0\t119392.0\n# 5\t391.0\t355.0\t138805.0\n```\n\n\n```python\ndf_clicks['MINUS'] = df_clicks['SHOP1'] - 100\nprint(df_clicks[['SHOP1', 'MINUS']].head())\n# => SHOP1\tMINUS\n# day\n# 1\t319.0\t219.0\n# 2\t292.0\t192.0\n# 3\t283.0\t183.0\n# 4\t328.0\t228.0\n# 5\t391.0\t291.0\n```\n\nИз примеров видно, что арифметические операции можно выполнять как между столбцами, так и между столбцом и другим объектом, например, числом. Этот прием называется укладыванием. Он также позволяет выполнять операции быстрее, чем проход по элементам в цикле.\n\n### Изменение типов данных\n\nТип столбцов важен для `DataFrame`. От него зависит корректность проведения тех или иных операций. Иногда его приходится изменять.\n\nПредположим, что нам в каких-то целях необходимо поработать с числовым столбцом, как со строковыми данными. Это можно легко сделать с помощью метода `astype()`:\n\n```python\nprint(df_clicks[['SHOP1', 'SHOP2']].info())\n# => <class 'pandas.core.frame.DataFrame'>\n# Int64Index: 28 entries, 1 to 28\n# Data columns (total 2 columns):\n# # Column Non-Null Count Dtype\n# --- ------ -------------- -----\n# 0 SHOP1 28 non-null float64\n# 1 SHOP2 27 non-null float64\n# dtypes: float64(2)\n# memory usage: 1.7 KB\n```\n\nПреобразуем тип для `SHOP1`:\n\n```python\ndf_clicks['SHOP1'] = df_clicks['SHOP1'].astype(str)\nprint(df_clicks[['SHOP1', 'SHOP2']].info())\n# => <class 'pandas.core.frame.DataFrame'>\n# Int64Index: 28 entries, 1 to 28\n# Data columns (total 2 columns):\n# # Column Non-Null Count Dtype\n# --- ------ -------------- -----\n# 0 SHOP1 28 non-null object\n# 1 SHOP2 27 non-null float64\n# dtypes: float64(1), object(1)\n# memory usage: 1.7+ KB\n```\n\nМетод `astype()` ожидает на вход тип объекта, к которому необходимо привести элементы столбца.\n\n### Замена элементов согласно словарю\n\nСуществуют преобразования данных в столбцах `DataFrame`, которые требуют заменить одно значение на другое. Если подстановку значений можно задать с помощью словаря, то достаточно воспользоваться методом `map()`.\n\nДопустим, 150 кликов и более — это хорошо, а меньше — это плохо. Добавим столбец с категорией значений 0 и 1 согласно данному условию:\n\n```python\ndf_clicks['GOOD_OR_BAD'] = df_clicks['SHOP2'].apply(lambda x: 0 if x < 150 else 1)\nprint(df_clicks[['SHOP2', 'GOOD_OR_BAD']].head())\n# => \tSHOP2\tGOOD_OR_BAD\n# day\n# 1\t-315.0\t 0\n# 2\t 174.0\t 1\n# 3\t 201.0\t 1\n# 4\t 264.0 1\n# 5\t 255.0\t 1\n```\n\nСоздадим словарь, согласно которому будет выполняться замена:\n\n```python\nmap_dict = {0:'BAD', 1:'GOOD'}\n```\n\nЗаменим значения столбца `GOOD_OR_BAD`:\n\n```python\ndf_clicks['GOOD_OR_BAD'] = df_clicks['GOOD_OR_BAD'].map(map_dict)\nprint(df_clicks[['SHOP2','GOOD_OR_BAD']].head())\n# => SHOP2\tGOOD_OR_BAD\n# day\n# 1\t-315.0\t BAD\n# 2\t 174.0\t GOOD\n# 3\t 201.0\t GOOD\n# 4\t 264.0\t GOOD\n# 5\t 255.0\t GOOD\n```\n\n## Выводы\n\nВ этом уроке мы познакомились с несколькими способами преобразования строк и столбцов объекта `DataFrame` библиотеки Pandas.\nОбычно выделяют два подхода:\n\n* Использование метода `apply()`\n* Применение векторизованных функций\n\nВ случае использования метода `apply()` можно выполнять сложное преобразование, но вычисления будут сравнительно долгими. В случае векторизованных функций все наоборот — получаем высокую производительность, но ограниченный функционал. Обычно аналитики делают свой выбор в зависимости от условий задачи.\n"},"lessonMember":null,"courseMember":null,"course":{"start_lesson":{"exercise":null,"units":[{"id":6604,"name":"theory","url":"/courses/python-pandas/lessons/intro/theory_unit"}],"links":[{"id":424128,"name":"10 minutes to pandas (официальный обзор)","url":"https://pandas.pydata.org/docs/getting_started/intro_tutorials/index.html"}],"ordered_units":[{"id":6604,"name":"theory","url":"/courses/python-pandas/lessons/intro/theory_unit"}],"id":2896,"slug":"intro","state":"approved","name":"Введение","course_order":100,"goal":"Знакомимся с библиотекой Pandas и типичным порядком работы с ней","self_study":null,"theory_video_provider":null,"theory_video_uid":null,"theory":"В этом курсе мы разберем библиотеку Pandas. Это один из наиболее популярных инструментов для обработки и анализа табличных данных на языке Python. После обучения вы сможете использовать инструментарий библиотеки Pandas в подготовке и анализе данных.\n\nВ этом вводном уроке мы разберем, по каким причинам аналитики используют эту библиотеку, и как выглядит типичный порядок работы с Pandas.\n\n## Причины появления библиотеки Pandas\n\nЧтобы организовать работу компаний и интернет-сервисов, нужны хранилища данных. Их организовывают по-разному:\n\n* Записки на бумажном носителе\n* Набор текстовых файлов\n* Электронные таблицы\n* Базы данных\n\nТабличные варианты хранения информации используются чаще, поскольку информация в них структурирована. Это удобно, когда требуется проводить анализ, расследовать инциденты, периодически подводить итоги и искать нужные данные.\n\nДля проектов с небольшим объемом производимых транзакций достаточно популярных средств работы с электронными таблицами. Это могут быть:\n\n* Десктопные приложения: Microsoft Excel, LibreOffice, OfficeSuite\n* Облачные решения: Google Sheets\n\nВ последнее время количество производимых операций и число пользователей или клиентов растет. Поэтому хранить данные в электронных таблицах становится накладным по следующим причинам:\n\n* Увеличение объема необходимой памяти для хранения\n* Недостаточная скорость записи данных\n* Увеличение времени на чтение и обработку данных\n\nВ таких случаях на практике используют реляционные системы управления базами данных — СУБД. Часто их называют просто базами данных. Наиболее популярные из них: PostgreSQL, MySQL, SQL Server.\n\nДля аналитика базы данных — это инструмент хранения большого количества данных в виде набора таблиц. Многие операции с электронными таблицами также реализуемы в базах данных, но с использованием особого языка — SQL.\n\nРост технологий анализа данных и машинного обучения подтолкнул многие компании к пересмотру подходов к хранению данных. Некоторые из них полностью перешли на базы данных, в некоторых часть данных осталась в виде электронных таблиц и документов. В последнем случае для анализа требуется широкий спектр инструментов.\n\nПопытки создания универсального способа для анализа табличных данных привели к созданию библиотеки Pandas.\n\nШирокое распространение библиотека Pandas получила по ряду причин:\n\n* Написана на популярном языке для анализа данных и машинного обучения — Python\n* Использует в основе библиотеку научных и быстрых вычислений — Numpy\n* Работает с широким спектром типов входных данных: csv, xsl, xslx, json\n* Подключается напрямую к базам данных\n* Имеет высокоуровневый интерфейс для преобразований данных и аналитики\n\n## Типичный порядок работы с библиотекой Pandas\n\nРассмотрим последовательность действий аналитика при работе с данными. Она содержит несколько ключевых шагов:\n\n* Чтение исходных данных\n* Анализ данных\n* Обработка данных\n* Сохранение результатов анализа и обработки исходных данных\n\nОдним из распространенных типов данных является csv — comma separated values. Это текстовые данные, в которых названия и значения разделяются запятой, точкой с запятой или табуляцией.\n\nДля примера рассмотрим файл `data/Shop_orders.csv` со значениями продаж четырех магазинов за одну неделю. Значения разделены запятой:\n\n```text\nWeekday,Shop_1,Shop_2,Shop_3,Shop_4\nmon,7,1,7,8\ntue,4,2,4,5\nwed,3,5,2,3\nthu,8,12,8,7\nfri,15,11,13,9\nsat,21,18,17,21\nsun,25,16,25,17\n```\n\nДля работы с данными импортируем модуль Pandas и воспользуемся нужным методом чтения:\n\n```python\n# Общепринятое сокращение для Pandas\nimport pandas as pd\n\ndf_orders = pd.read_csv('data/Shop_orders.csv', index_col=0)\n```\n\nПомимо пути к файлу необходимо указать колонку, которую считаем за индекс. В нашем случае это нулевая колонка — Weekday.\n\nДля обзора считанных данных воспользуемся методом `head()`, который покажет первые пять строк данных:\n\n```python\nprint(df_orders.head())\n```\n\n```text\n Shop_1 Shop_2 Shop_3 Shop_4\nWeekday\nmon 7 1 7 8\ntue 4 2 4 5\nwed 3 5 2 3\nthu 8 12 8 7\nfri 15 11 13 9\n```\n\nПосмотрим на основные статистические показатели:\n\n```python\nprint(df_orders.describe())\n```\n\n```text\n Shop_1 Shop_2 Shop_3 Shop_4\ncount 7.000000 7.000000 7.000000 7.000000\nmean 11.857143 9.285714 10.857143 10.000000\nstd 8.610625 6.725927 8.071113 6.557439\nmin 3.000000 1.000000 2.000000 3.000000\n25% 5.500000 3.500000 5.500000 6.000000\n50% 8.000000 11.000000 8.000000 8.000000\n75% 18.000000 14.000000 15.000000 13.000000\nmax 25.000000 18.000000 25.000000 21.000000\n```\n\nОдним методом удалось посмотреть среднее значение и отклонение от него, минимальное и максимальное значения и ряд персентильных значений.\n\nТакже одним методом можно достать средние значения по каждому магазину:\n\n```python\nprint(df_orders.mean())\n```\n\n```text\nShop_1 11.857143\nShop_2 9.285714\nShop_3 10.857143\nShop_4 10.000000\ndtype: float64\n```\n\nОстановимся в подготовке данных на центрировании значений продаж по каждому магазину. Вычтем из значений продаж среднее для данного магазина:\n\n```python\ndf_orders_centered = df_orders - df_orders.mean()\nprint(df_orders_centered)\n```\n\n```text\n Shop_1 Shop_2 Shop_3 Shop_4\nWeekday\nmon -4.857143 -8.285714 -3.857143 -2.0\ntue -7.857143 -7.285714 -6.857143 -5.0\nwed -8.857143 -4.285714 -8.857143 -7.0\nthu -3.857143 2.714286 -2.857143 -3.0\nfri 3.142857 1.714286 2.142857 -1.0\nsat 9.142857 8.714286 6.142857 11.0\nsun 13.142857 6.714286 14.142857 7.0\n```\n\nОстается сохранить полученный результат:\n\n```python\ndf_orders_centered.to_csv('data/Shop_orders_centered.csv')\n```\n\nВ директории с исходным файлом теперь лежит преобразованный вариант с подготовленными данными. Работа аналитика завершена.\n\n## Выводы\n\nВ рамках данного курса рассматривается библиотека Pandas. Это один из наиболее популярных инструментов для обработки и анализа табличных данных на языке Python. Большое количество поддерживаемых типов данных и функций для их обработки, высокая скорость работы и дружелюбный интерфейс выделяют ее среди конкурентов.\n\nЧтобы освоить основные навыки работы с данной библиотекой, предлагаем пройти несколько шагов:\n\n1. Понять основной порядок работы с данными\n2. Узнать про интерфейсы чтения и записи данных\n3. Поработать с индексированием\n4. Научиться фильтровать значения в таблицах\n5. Применить функции для обработки строк и столбцов\n6. Построить сложные агрегации и сводные таблицы\n7. Объединить несколько таблиц в одну\n\nПосле этих тем вы сможете уверенно использовать инструментарий библиотеки Pandas в подготовке и анализе данных.\n"},"id":284,"slug":"python-pandas","challenges_count":3,"name":"Python: Pandas","allow_indexing":true,"state":"approved","course_state":"finished","pricing_type":"paid","description":"На этом курсе вы изучите анализ данных с помощью библиотеки Pandas. Вы узнаете много нового о порядке работы с данными в Python, научитесь фильтровать данные, обрабатывать строки и столбцы в таблицах. В итоге вы освоите все необходимые возможности Pandas: научитесь читать и записывать данные в популярные табличные форматы, строить сложные агрегации, объединять несколько таблиц в одну.\n\nБиблиотека Pandas пригодится, если вам интересна подготовка данных и их анализ с использованием языка Python. Знания из этого курса позволят вам преобразовывать неструктурированные данные в табличный вид для наглядности.","kind":"basic","updated_at":"2026-01-20T11:45:43.407Z","language":"python","duration_cache":43560,"skills":["Поймете, как осуществить чтение и запись таблиц в популярные табличные форматы","Научитесь фильтровать значения и оперировать с их подмножествами","Познакомитесь с агрегированием и группированием данных","Освоите объединение и изменение формы таблиц"],"keywords":[],"lessons_count":10,"cover":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NzM3MywicHVyIjoiYmxvYl9pZCJ9fQ==--a2bcce00d4df3d786af4d6b42354890f34a47b08/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJwbmciLCJyZXNpemVfdG9fZmlsbCI6WzYwMCw0MDBdfSwicHVyIjoidmFyaWF0aW9uIn19--6067466c2912ca31a17eddee04b8cf2a38c6ad17/image.png"},"recommendedLandings":[{"stack":{"id":55,"slug":"data-analytics","title":"Аналитик данных","audience":"for_beginners","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"finished","order":80,"duration_in_months":7},"id":98,"slug":"data-analytics","title":"Аналитик данных","subtitle":"Изучите SQL, Python, Pandas, Tableau, Superset и методы A/B-тестов.","subtitle_for_lists":"Изучите SQL, Python, Pandas, Tableau, Superset и методы A/B-тестов.","locale":"ru","current":true,"duration_in_months_text":"7 месяцев","stack_slug":"data-analytics","price_text":"от 4 395 ₽","duration_text":"7 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzY1MywicHVyIjoiYmxvYl9pZCJ9fQ==--5107185de77b3481e0a836f9fc7326c4e1b77be4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Data%20extraction-pana.png"},{"stack":{"id":60,"slug":"python-for-data-analysts","title":"Python для анализа данных","audience":"for_beginners","start_type":"anytime","pricing_model":"subscription","priority":"medium","kind":"track","state":"published","stack_state":"finished","order":1300,"duration_in_months":3},"id":108,"slug":"python-for-data-analysts","title":"Python для анализа данных","subtitle":"Навык работы с большими данными для повышения квалификации и решения сложных инженерных и аналитических задач","subtitle_for_lists":"Изучите Python для больших данных и аналитических задач","locale":"ru","current":true,"duration_in_months_text":"3 месяца","stack_slug":"python-for-data-analysts","price_text":"от 3 900 ₽","duration_text":"3 месяца","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk1OSwicHVyIjoiYmxvYl9pZCJ9fQ==--39f076671bc03debdf48e861bbd4c34c3fd4aac8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Data%20extraction-bro.png"},{"stack":{"id":227,"slug":"bi-analyst","title":"BI-аналитик","audience":"for_beginners","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"not_finished","order":null,"duration_in_months":7},"id":359,"slug":"bi-analyst","title":"BI-аналитик","subtitle":"Изучите SQL, BI-инструменты и визуализацию данных","subtitle_for_lists":"Изучите SQL, BI-инструменты и визуализацию данных","locale":"ru","current":true,"duration_in_months_text":"7 месяцев","stack_slug":"bi-analyst","price_text":"от 4 395 ₽","duration_text":"7 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDg3MSwicHVyIjoiYmxvYl9pZCJ9fQ==--8175585f43b5401994e29b3ae73d76963d942512/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Browser%20stats-bro.png"},{"stack":{"id":462,"slug":"product-analyst","title":"Продуктовый аналитик","audience":"for_beginners","start_type":"weekly","pricing_model":"purchase","priority":"high","kind":"profession","state":"published","stack_state":"not_finished","order":500,"duration_in_months":7},"id":591,"slug":"product-analyst","title":"Продуктовый аналитик","subtitle":"Изучите продуктовые метрики, A/B-тесты и анализ пользовательских данных","subtitle_for_lists":"Изучите продуктовые метрики, A/B-тесты и анализ пользовательских данных","locale":"ru","current":true,"duration_in_months_text":"7 месяцев","stack_slug":"product-analyst","price_text":"от 4 395 ₽","duration_text":"7 месяцев","cover_list_variant":"https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDg2MiwicHVyIjoiYmxvYl9pZCJ9fQ==--04a703ca18d7bf689064f1f3c2721058bd5564e4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Statistics-bro.png"}],"lessonMemberUnit":null,"accessToLearnUnitExists":false,"accessToCourseExists":false},"url":"/courses/python-pandas/lessons/pandas-column-functions/theory_unit","version":"8f286f6358a90a7bef2263b3a6edf5a90a94fa42","encryptHistory":false,"clearHistory":false}"><style data-mantine-styles="true">:root, :host{--mantine-font-family: Arial, sans-serif;--mantine-font-family-headings: Arial, sans-serif;--mantine-heading-font-weight: normal;--mantine-radius-default: 0rem;--mantine-primary-color-filled: var(--mantine-color-indigo-filled);--mantine-primary-color-filled-hover: var(--mantine-color-indigo-filled-hover);--mantine-primary-color-light: var(--mantine-color-indigo-light);--mantine-primary-color-light-hover: var(--mantine-color-indigo-light-hover);--mantine-primary-color-light-color: var(--mantine-color-indigo-light-color);--mantine-spacing-xxl: calc(4rem * var(--mantine-scale));--mantine-font-size-xs: 12px;--mantine-font-size-sm: 14px;--mantine-font-size-md: 16px;--mantine-font-size-lg: clamp(16.0000px, calc(15.2727px + 0.2273vw), 18.0000px);--mantine-font-size-xl: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-display-3: clamp(32.0000px, calc(26.1818px + 1.8182vw), 48.0000px);--mantine-font-size-display-2: clamp(36.0000px, calc(25.8182px + 3.1818vw), 64.0000px);--mantine-font-size-display-1: clamp(40.0000px, calc(25.4545px + 4.5455vw), 80.0000px);--mantine-font-size-h1: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-font-size-h2: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-font-size-h3: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-font-size-h4: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-font-size-h5: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-font-size-h6: 1rem;--mantine-primary-color-0: var(--mantine-color-indigo-0);--mantine-primary-color-1: var(--mantine-color-indigo-1);--mantine-primary-color-2: var(--mantine-color-indigo-2);--mantine-primary-color-3: var(--mantine-color-indigo-3);--mantine-primary-color-4: var(--mantine-color-indigo-4);--mantine-primary-color-5: var(--mantine-color-indigo-5);--mantine-primary-color-6: var(--mantine-color-indigo-6);--mantine-primary-color-7: var(--mantine-color-indigo-7);--mantine-primary-color-8: var(--mantine-color-indigo-8);--mantine-primary-color-9: var(--mantine-color-indigo-9);--mantine-color-red-0: #ffeaea;--mantine-color-red-1: #fed4d4;--mantine-color-red-2: #f4a7a8;--mantine-color-red-3: #ec7878;--mantine-color-red-4: #e55050;--mantine-color-red-5: #e03131;--mantine-color-red-6: #e02829;--mantine-color-red-7: #c71a1c;--mantine-color-red-8: #b21218;--mantine-color-red-9: #9c0411;--mantine-color-violet-0: #fce9ff;--mantine-color-violet-1: #f1cfff;--mantine-color-violet-2: #e09bff;--mantine-color-violet-3: #d16fff;--mantine-color-violet-4: #be37fe;--mantine-color-violet-5: #b51afe;--mantine-color-violet-6: #b009ff;--mantine-color-violet-7: #9b00e4;--mantine-color-violet-8: #8a00cc;--mantine-color-violet-9: #7800b3;--mantine-color-indigo-0: #edecff;--mantine-color-indigo-1: #d6d5fe;--mantine-color-indigo-2: #aaa9f4;--mantine-color-indigo-3: #7b79eb;--mantine-color-indigo-4: #5451e4;--mantine-color-indigo-5: #3b37e0;--mantine-color-indigo-6: #2d2adf;--mantine-color-indigo-7: #1f1ec7;--mantine-color-indigo-8: #1819b2;--mantine-color-indigo-9: #0c149e;--mantine-color-cyan-0: #dffdff;--mantine-color-cyan-1: #caf5ff;--mantine-color-cyan-2: #99e8ff;--mantine-color-cyan-3: #64daff;--mantine-color-cyan-4: #3ccffe;--mantine-color-cyan-5: #24c8fe;--mantine-color-cyan-6: #00c2ff;--mantine-color-cyan-7: #00ade4;--mantine-color-cyan-8: #009acd;--mantine-color-cyan-9: #0085b5;--mantine-color-green-0: #e9fdec;--mantine-color-green-1: #d7f6dc;--mantine-color-green-2: #b0eab9;--mantine-color-green-3: #86df94;--mantine-color-green-4: #62d574;--mantine-color-green-5: #4ccf5f;--mantine-color-green-6: #3fcc54;--mantine-color-green-7: #2fb344;--mantine-color-green-8: #25a03b;--mantine-color-green-9: #138a2e;--mantine-color-yellow-0: #fff7e2;--mantine-color-yellow-1: #ffeecd;--mantine-color-yellow-2: #ffdc9c;--mantine-color-yellow-3: #ffc966;--mantine-color-yellow-4: #feb93a;--mantine-color-yellow-5: #feae1e;--mantine-color-yellow-6: #ffa90f;--mantine-color-yellow-8: #ca8200;--mantine-color-yellow-9: #af7000;--mantine-h1-font-size: clamp(28.0000px, calc(23.6364px + 1.3636vw), 40.0000px);--mantine-h1-font-weight: normal;--mantine-h2-font-size: clamp(24.0000px, calc(21.0909px + 0.9091vw), 32.0000px);--mantine-h2-font-weight: normal;--mantine-h3-font-size: clamp(20.0000px, calc(17.0909px + 0.9091vw), 28.0000px);--mantine-h3-font-weight: normal;--mantine-h4-font-size: clamp(16.0000px, calc(13.0909px + 0.9091vw), 24.0000px);--mantine-h4-font-weight: normal;--mantine-h5-font-size: clamp(16.0000px, calc(14.5455px + 0.4545vw), 20.0000px);--mantine-h5-font-weight: normal;--mantine-h6-font-size: 1rem;--mantine-h6-font-weight: normal;}
:root[data-mantine-color-scheme="dark"], :host([data-mantine-color-scheme="dark"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-dark-filled: var(--mantine-color-dark-5);--mantine-color-dark-filled-hover: var(--mantine-color-dark-6);--mantine-color-dark-light: rgba(105, 105, 105, 0.15);--mantine-color-dark-light-hover: rgba(105, 105, 105, 0.2);--mantine-color-dark-light-color: var(--mantine-color-dark-0);--mantine-color-dark-outline: var(--mantine-color-dark-1);--mantine-color-dark-outline-hover: rgba(184, 184, 184, 0.05);--mantine-color-gray-filled: var(--mantine-color-gray-5);--mantine-color-gray-filled-hover: var(--mantine-color-gray-6);--mantine-color-gray-light: rgba(222, 226, 230, 0.15);--mantine-color-gray-light-hover: rgba(222, 226, 230, 0.2);--mantine-color-gray-light-color: var(--mantine-color-gray-0);--mantine-color-gray-outline: var(--mantine-color-gray-1);--mantine-color-gray-outline-hover: rgba(241, 243, 245, 0.05);--mantine-color-red-filled: var(--mantine-color-red-5);--mantine-color-red-filled-hover: var(--mantine-color-red-6);--mantine-color-red-light: rgba(236, 120, 120, 0.15);--mantine-color-red-light-hover: rgba(236, 120, 120, 0.2);--mantine-color-red-light-color: var(--mantine-color-red-0);--mantine-color-red-outline: var(--mantine-color-red-1);--mantine-color-red-outline-hover: rgba(254, 212, 212, 0.05);--mantine-color-pink-filled: var(--mantine-color-pink-5);--mantine-color-pink-filled-hover: var(--mantine-color-pink-6);--mantine-color-pink-light: rgba(250, 162, 193, 0.15);--mantine-color-pink-light-hover: rgba(250, 162, 193, 0.2);--mantine-color-pink-light-color: var(--mantine-color-pink-0);--mantine-color-pink-outline: var(--mantine-color-pink-1);--mantine-color-pink-outline-hover: rgba(255, 222, 235, 0.05);--mantine-color-grape-filled: var(--mantine-color-grape-5);--mantine-color-grape-filled-hover: var(--mantine-color-grape-6);--mantine-color-grape-light: rgba(229, 153, 247, 0.15);--mantine-color-grape-light-hover: rgba(229, 153, 247, 0.2);--mantine-color-grape-light-color: var(--mantine-color-grape-0);--mantine-color-grape-outline: var(--mantine-color-grape-1);--mantine-color-grape-outline-hover: rgba(243, 217, 250, 0.05);--mantine-color-violet-filled: var(--mantine-color-violet-5);--mantine-color-violet-filled-hover: var(--mantine-color-violet-6);--mantine-color-violet-light: rgba(209, 111, 255, 0.15);--mantine-color-violet-light-hover: rgba(209, 111, 255, 0.2);--mantine-color-violet-light-color: var(--mantine-color-violet-0);--mantine-color-violet-outline: var(--mantine-color-violet-1);--mantine-color-violet-outline-hover: rgba(241, 207, 255, 0.05);--mantine-color-indigo-filled: var(--mantine-color-indigo-5);--mantine-color-indigo-filled-hover: var(--mantine-color-indigo-6);--mantine-color-indigo-light: rgba(123, 121, 235, 0.15);--mantine-color-indigo-light-hover: rgba(123, 121, 235, 0.2);--mantine-color-indigo-light-color: var(--mantine-color-indigo-0);--mantine-color-indigo-outline: var(--mantine-color-indigo-1);--mantine-color-indigo-outline-hover: rgba(214, 213, 254, 0.05);--mantine-color-blue-filled: var(--mantine-color-blue-5);--mantine-color-blue-filled-hover: var(--mantine-color-blue-6);--mantine-color-blue-light: rgba(116, 192, 252, 0.15);--mantine-color-blue-light-hover: rgba(116, 192, 252, 0.2);--mantine-color-blue-light-color: var(--mantine-color-blue-0);--mantine-color-blue-outline: var(--mantine-color-blue-1);--mantine-color-blue-outline-hover: rgba(208, 235, 255, 0.05);--mantine-color-cyan-filled: var(--mantine-color-cyan-5);--mantine-color-cyan-filled-hover: var(--mantine-color-cyan-6);--mantine-color-cyan-light: rgba(100, 218, 255, 0.15);--mantine-color-cyan-light-hover: rgba(100, 218, 255, 0.2);--mantine-color-cyan-light-color: var(--mantine-color-cyan-0);--mantine-color-cyan-outline: var(--mantine-color-cyan-1);--mantine-color-cyan-outline-hover: rgba(202, 245, 255, 0.05);--mantine-color-teal-filled: var(--mantine-color-teal-5);--mantine-color-teal-filled-hover: var(--mantine-color-teal-6);--mantine-color-teal-light: rgba(99, 230, 190, 0.15);--mantine-color-teal-light-hover: rgba(99, 230, 190, 0.2);--mantine-color-teal-light-color: var(--mantine-color-teal-0);--mantine-color-teal-outline: var(--mantine-color-teal-1);--mantine-color-teal-outline-hover: rgba(195, 250, 232, 0.05);--mantine-color-green-filled: var(--mantine-color-green-5);--mantine-color-green-filled-hover: var(--mantine-color-green-6);--mantine-color-green-light: rgba(134, 223, 148, 0.15);--mantine-color-green-light-hover: rgba(134, 223, 148, 0.2);--mantine-color-green-light-color: var(--mantine-color-green-0);--mantine-color-green-outline: var(--mantine-color-green-1);--mantine-color-green-outline-hover: rgba(215, 246, 220, 0.05);--mantine-color-lime-filled: var(--mantine-color-lime-5);--mantine-color-lime-filled-hover: var(--mantine-color-lime-6);--mantine-color-lime-light: rgba(192, 235, 117, 0.15);--mantine-color-lime-light-hover: rgba(192, 235, 117, 0.2);--mantine-color-lime-light-color: var(--mantine-color-lime-0);--mantine-color-lime-outline: var(--mantine-color-lime-1);--mantine-color-lime-outline-hover: rgba(233, 250, 200, 0.05);--mantine-color-yellow-filled: var(--mantine-color-yellow-5);--mantine-color-yellow-filled-hover: var(--mantine-color-yellow-6);--mantine-color-yellow-light: rgba(255, 201, 102, 0.15);--mantine-color-yellow-light-hover: rgba(255, 201, 102, 0.2);--mantine-color-yellow-light-color: var(--mantine-color-yellow-0);--mantine-color-yellow-outline: var(--mantine-color-yellow-1);--mantine-color-yellow-outline-hover: rgba(255, 238, 205, 0.05);--mantine-color-orange-filled: var(--mantine-color-orange-5);--mantine-color-orange-filled-hover: var(--mantine-color-orange-6);--mantine-color-orange-light: rgba(255, 192, 120, 0.15);--mantine-color-orange-light-hover: rgba(255, 192, 120, 0.2);--mantine-color-orange-light-color: var(--mantine-color-orange-0);--mantine-color-orange-outline: var(--mantine-color-orange-1);--mantine-color-orange-outline-hover: rgba(255, 232, 204, 0.05);--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-9) 0%, var(--mantine-color-cyan-7) 100%);--app-color-surface: #2e2e2e;}
:root[data-mantine-color-scheme="light"], :host([data-mantine-color-scheme="light"]){--mantine-color-anchor: var(--mantine-color-text);--mantine-color-dimmed: #495057;--mantine-color-red-light: rgba(224, 40, 41, 0.1);--mantine-color-red-light-hover: rgba(224, 40, 41, 0.12);--mantine-color-red-outline-hover: rgba(224, 40, 41, 0.05);--mantine-color-violet-light: rgba(176, 9, 255, 0.1);--mantine-color-violet-light-hover: rgba(176, 9, 255, 0.12);--mantine-color-violet-outline-hover: rgba(176, 9, 255, 0.05);--mantine-color-indigo-light: rgba(45, 42, 223, 0.1);--mantine-color-indigo-light-hover: rgba(45, 42, 223, 0.12);--mantine-color-indigo-outline-hover: rgba(45, 42, 223, 0.05);--mantine-color-cyan-light: rgba(0, 194, 255, 0.1);--mantine-color-cyan-light-hover: rgba(0, 194, 255, 0.12);--mantine-color-cyan-outline-hover: rgba(0, 194, 255, 0.05);--mantine-color-green-light: rgba(63, 204, 84, 0.1);--mantine-color-green-light-hover: rgba(63, 204, 84, 0.12);--mantine-color-green-outline-hover: rgba(63, 204, 84, 0.05);--mantine-color-yellow-light: rgba(255, 169, 15, 0.1);--mantine-color-yellow-light-hover: rgba(255, 169, 15, 0.12);--mantine-color-yellow-outline-hover: rgba(255, 169, 15, 0.05);--app-color-surface: #f1f3f5;--app-cta-gradient: linear-gradient(90deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-5) 100%);}</style><style data-mantine-styles="classes">@media (max-width: 35.99375em) {.mantine-visible-from-xs {display: none !important;}}@media (min-width: 36em) {.mantine-hidden-from-xs {display: none !important;}}@media (max-width: 47.99375em) {.mantine-visible-from-sm {display: none !important;}}@media (min-width: 48em) {.mantine-hidden-from-sm {display: none !important;}}@media (max-width: 61.99375em) {.mantine-visible-from-md {display: none !important;}}@media (min-width: 62em) {.mantine-hidden-from-md {display: none !important;}}@media (max-width: 74.99375em) {.mantine-visible-from-lg {display: none !important;}}@media (min-width: 75em) {.mantine-hidden-from-lg {display: none !important;}}@media (max-width: 87.99375em) {.mantine-visible-from-xl {display: none !important;}}@media (min-width: 88em) {.mantine-hidden-from-xl {display: none !important;}}</style><div style="position:absolute;top:0rem" class=""></div><div style="max-width:var(--container-size-xl);height:100%;min-height:0rem" class=""><style data-mantine-styles="inline">.__m__-_R_5ub_{--grid-gutter:0rem;}</style><div style="height:100%;min-height:0rem" class="m_410352e9 mantine-Grid-root __m__-_R_5ub_"><div class="m_dee7bd2f mantine-Grid-inner" style="height:100%"><style data-mantine-styles="inline">.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:91.66666666666667%;--col-max-width:91.66666666666667%;}@media(min-width: 48em){.__m__-_R_rdub_{--col-flex-grow:auto;--col-flex-basis:83.33333333333334%;--col-max-width:83.33333333333334%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem;display:flex" class="m_96bdd299 mantine-Grid-col __m__-_R_rdub_"><style data-mantine-styles="inline">.__m__-_R_6qrdub_{margin-top:0rem;padding-inline:var(--mantine-spacing-xs);width:100%;}@media(min-width: 48em){.__m__-_R_6qrdub_{margin-top:var(--mantine-spacing-xl);width:80%;}}@media(min-width: 62em){.__m__-_R_6qrdub_{padding-inline:var(--mantine-spacing-xl);}}</style><div style="margin-inline:auto;max-width:var(--mantine-breakpoint-xl)" class="__m__-_R_6qrdub_"><div style="color:var(--mantine-color-dimmed)" class="m_4451eb3a mantine-Center-root" data-inline="true"><div style="--ti-size:var(--ti-size-xs);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;margin-inline-end:calc(0.125rem * var(--mantine-scale));color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="xs"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-lock "><path d="M5 13a2 2 0 0 1 2 -2h10a2 2 0 0 1 2 2v6a2 2 0 0 1 -2 2h-10a2 2 0 0 1 -2 -2v-6"></path><path d="M11 16a1 1 0 1 0 2 0a1 1 0 0 0 -2 0"></path><path d="M8 11v-4a4 4 0 1 1 8 0v4"></path></svg></div><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Python: Pandas</p></div><h1 style="--title-fw:var(--mantine-h1-font-weight);--title-lh:var(--mantine-h1-line-height);--title-fz:var(--mantine-h1-font-size);margin-bottom:var(--mantine-spacing-xl)" class="m_8a5d1357 mantine-Title-root" data-order="1">Теория: Применение функций к столбцам и строкам таблицы</h1><script type="application/ld+json">{"@context":"https://schema.org","@type":"LearningResource","name":"Применение функций к столбцам и строкам таблицы","inLanguage":"ru","isPartOf":{"@type":"LearningResource","name":"Python: Pandas"},"isAccessibleForFree":"False","hasPart":{"@type":"WebPageElement","isAccessibleForFree":"False","cssSelector":".paywalled"}}</script><div class=""><div style="--alert-color:var(--mantine-color-indigo-light-color);margin-bottom:var(--mantine-spacing-lg);font-size:var(--mantine-font-size-lg)" class="m_66836ed3 mantine-Alert-root" id="mantine-_R_remqrdub_" role="alert" aria-describedby="mantine-_R_remqrdub_-body" aria-labelledby="mantine-_R_remqrdub_-title"><div class="m_a5d60502 mantine-Alert-wrapper"><div class="m_667f2a6a mantine-Alert-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-rocket "><path d="M4 13a8 8 0 0 1 7 7a6 6 0 0 0 3 -5a9 9 0 0 0 6 -8a3 3 0 0 0 -3 -3a9 9 0 0 0 -8 6a6 6 0 0 0 -5 3"></path><path d="M7 14a6 6 0 0 0 -3 6a6 6 0 0 0 6 -3"></path><path d="M14 9a1 1 0 1 0 2 0a1 1 0 1 0 -2 0"></path></svg></div><div class="m_667c2793 mantine-Alert-body"><div class="m_6a03f287 mantine-Alert-title"><span id="mantine-_R_remqrdub_-title" class="m_698f4f23 mantine-Alert-label">Полный доступ к материалам</span></div><div id="mantine-_R_remqrdub_-body" class="m_7fa78076 mantine-Alert-message"><div style="--group-gap:var(--mantine-spacing-md);--group-align:center;--group-justify:space-between;--group-wrap:wrap" class="m_4081bf90 mantine-Group-root"><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Зарегистрируйтесь и получите доступ к этому и десяткам других курсов</p><a style="--button-height:var(--button-height-xs);--button-padding-x:var(--button-padding-x-xs);--button-fz:var(--mantine-font-size-xs);--button-bg:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-hover:linear-gradient(45deg, var(--mantine-color-blue-filled) 0%, var(--mantine-color-cyan-filled) 100%);--button-color:var(--mantine-color-white);--button-bd:none" class="mantine-focus-auto mantine-active m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root" data-variant="gradient" data-size="xs" href="/u/new"><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">Зарегистрироваться</span></span></a></div></div></div></div></div><div class="paywalled m_d08caa0 mantine-Typography-root"><p>В процессе обработки и анализа данных их значения могут преобразовываться. При этом можно оперировать с конкретными элементами или же применять действия одновременно ко всем в столбце или строке. Последний вариант является более предпочтительным в использовании, так как увеличивает производительность при обработке больших объемов данных.</p>
<p>В этом уроке мы познакомимся с методами, которые позволяют уйти от поэлементных операций и применять сценарии обработки ко всему набору данных.</p>
<h2 id="heading-2-1">Преобразования данных методом apply()</h2>
<p>Метод <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code> — это инструмент для преобразования объекта <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">DataFrame</code>. <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">аpply()</code> можно применять как к одному столбцу, так и к нескольким.</p>
<p>Разберем каждую ситуацию подробнее.</p>
<h3 id="heading-3-2">apply() для преобразования одного столбца</h3>
<p>Рассмотрим пример на данных о кликах на сайте с четырьмя магазинами. Допустим, произошла техническая ошибка, и по первому магазину количество кликов завышено на 50 штук. Исправим это с помощью <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code>. Подгрузим данные:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">import pandas as pd
df_clicks = pd.read_csv('./data/Cite_clicks.csv', index_col=0)
print(df_clicks.head())
# => SHOP1 SHOP2 SHOP3 SHOP4
# day
# 1 319.0 -265.0 319.0 328.0
# 2 292.0 274.0 292.0 301.0
# 3 283.0 301.0 274.0 283.0
# 4 328.0 364.0 328.0 NaN
# 5 391.0 355.0 373.0 337.0</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Уменьшим значения продаж для первого магазина на 50 пунктов:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">df_clicks['SHOP1'] = df_clicks['SHOP1'].apply(lambda x: x - 50)
print(df_clicks.head())
# => SHOP1 SHOP2 SHOP3 SHOP4
# day
# 1 269.0 -265.0 319.0 328.0
# 2 242.0 274.0 292.0 301.0
# 3 233.0 301.0 274.0 283.0
# 4 278.0 364.0 328.0 NaN
# 5 341.0 355.0 373.0 337.0</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>В аргументах <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code> находится лямбда-функция языка Python. У нее нет названия, и она используется только в конкретном участке кода. В нашем случае лямбда-функция принимает на вход параметр <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">x</code> и возвращает <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">x - 50</code>. Каждое значение в столбце — это вход указанной функции. Новый столбец формируется из ее выходных значений.</p>
<p>Теперь представим, что появилась дополнительная информация. Количество кликов у магазина 2 завышено на 50 штук, если кликов не более 200, и на 100, если кликов более 200. Попробуем исправить и эту ошибку:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def correct_clicks(x):
if x < 200:
return x - 50
else:
return x - 100
df_clicks['SHOP2'] = df_clicks['SHOP2'].apply(correct_clicks)
print(df_clicks.head())
# => SHOP1 SHOP2 SHOP3 SHOP4
# day
# 1 269.0 -315.0 319.0 328.0
# 2 242.0 174.0 292.0 301.0
# 3 233.0 201.0 274.0 283.0
# 4 278.0 264.0 328.0 NaN
# 5 341.0 255.0 373.0 337.0</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Здесь вместо лямбда-функции в аргументах метода <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code> отдельная функция <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">correct_clicks()</code>. Она принимает на вход каждый элемент столбца и выполняет над ним описанное выше преобразование.</p>
<p>Теперь мы узнаем, что у второго столбца порог 200 кликов — это порог между разницей в 50 или 100, у третьего этот порог равен 150 и у четвертого — 250. Выполним параметризацию функции <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">correct_clicks()</code>:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def correct_clicks(x, threshold):
if x < threshold:
return x - 50
else:
return x - 100
df_clicks['SHOP3'] = df_clicks['SHOP3'].apply(lambda x: correct_clicks(x, 150))
df_clicks['SHOP4'] = df_clicks['SHOP4'].apply(lambda x: correct_clicks(x, 250))
print(df_clicks.head())
# => SHOP1 SHOP2 SHOP3 SHOP4
# day
# 1 269.0 -315.0 169.0 328.0
# 2 242.0 174.0 142.0 301.0
# 3 233.0 201.0 124.0 283.0
# 4 278.0 264.0 178.0 NaN
# 5 341.0 255.0 173.0 337.0</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>В случае параметризации необходимо использовать <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">correct_clicks()</code> в теле лямда-функции.</p>
<h3 id="heading-3-3">apply() для преобразования нескольких столбцов</h3>
<p>Предположим, что нам необходимо найти наибольшее число кликов за каждый день среди магазинов 1 и 3. Сформируем новый столбец <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">MAX_SHOP1_SHOP3</code>:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">df_clicks['SHOP1'] = df_clicks['SHOP1'].fillna(df_clicks['SHOP1'].mean())
df_clicks['SHOP3'] = df_clicks['SHOP3'].fillna(df_clicks['SHOP3'].mean())
df_clicks['MAX_SHOP1_SHOP3'] = df_clicks.apply(lambda x: max(x['SHOP1'], x['SHOP3']), axis=1)
print(df_clicks.head())
# => SHOP1 SHOP2 SHOP3 SHOP4 MAX_SHOP1_SHOP3
# day
# 1 269.0 -315.0 169.0 328.0 269.0
# 2 242.0 174.0 142.0 301.0 242.0
# 3 233.0 201.0 124.0 283.0 233.0
# 4 278.0 264.0 178.0 NaN 278.0
# 5 341.0 255.0 173.0 337.0 341.0</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>В первых двух строчках мы заполнили пропуски в данных средними значениями с помощью метода <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">fillna()</code>. Это нужно, чтобы не было ошибок при вызове функции <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">max()</code>. Далее <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code> применяется ко всему <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">DataFrame</code>. Параметр <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">axis</code> задает направление обхода набора данных:</p>
<ul>
<li>0 задает обход по столбцам</li>
<li>1 задает обход по строкам</li>
</ul>
<p>Мы использовали значение 1, так в качестве аргумента <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">x</code> лямбда-функции выступают строки набора данных. Так как мы ищем максимум среди 1 и 3 магазинов, то обращаемся к соответствующим значениям по ключам магазинов: <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">SHOP1</code> и <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">SHOP3</code>.</p>
<p>Теперь учтем следующую информацию: если максимум окажется больше, чем 200, то мы должны заполнить столбец числом -1. Это будет говорить о некоторой технической ошибке:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">def correct_max(x, threshold):
if max(x['SHOP1'], x['SHOP3']) > threshold:
return -1
return max(x['SHOP1'], x['SHOP3'])
df_clicks['MAX_SHOP1_SHOP3_CORRECT'] = df_clicks.apply(lambda x: correct_max(x, 200), axis=1)
print(df_clicks.head())
# => SHOP1 SHOP2 SHOP3 SHOP4 MAX_SHOP1_SHOP3 MAX_SHOP1_SHOP3_CORRECT
# day
# 1 269.0 -315.0 169.0 328.0 269.0 -1.0
# 2 242.0 174.0 142.0 301.0 242.0 -1.0
# 3 233.0 201.0 124.0 283.0 233.0 -1.0
# 4 278.0 264.0 178.0 NaN 278.0 -1.0
# 5 341.0 255.0 173.0 337.0 341.0 -1.0</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<h2 id="heading-2-4">Векторизованные функции</h2>
<p>В отличие от метода <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code> векторизованные функции преобразовывают столбцы не поэлементно, а целыми списками. Это позволяет выполнять вычисления быстрее. Найдем сумму кликов двух магазинов с помощью разных подходов, и сравним скорость их выполнения:</p>
<div class="m_5cb1b9c8 mantine-CodeHighlightTabs-root"><div style="--sa-corner-width:0px;--sa-corner-height:0px" class="m_7b14120b mantine-CodeHighlightTabs-filesScrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><div class="m_38d99e51 mantine-CodeHighlightTabs-files"><button class="mantine-focus-auto m_5cac2e62 mantine-CodeHighlightTabs-file m_87cf2631 mantine-UnstyledButton-root" data-active="true" type="button"><span>python</span></button><button class="mantine-focus-auto m_5cac2e62 mantine-CodeHighlightTabs-file m_87cf2631 mantine-UnstyledButton-root" type="button"><span>python</span></button></div></div></div><div data-orientation="horizontal" class="m_c44ba933 mantine-ScrollArea-scrollbar" data-hidden="true" style="position:absolute;--sa-thumb-width:18px" data-mantine-scrollbar="true"></div><div class="m_c44ba933 mantine-ScrollArea-scrollbar" data-hidden="true" data-orientation="vertical" style="position:absolute;--sa-thumb-height:18px" data-mantine-scrollbar="true"></div></div><div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlightTabs-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlightTabs-controls" data-with-offset="true"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlightTabs-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlightTabs-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlightTabs-pre" data-with-offset="true"><code class="m_5caae6d3 mantine-CodeHighlightTabs-code">%time df_clicks['SUM'] = df_clicks.apply(lambda x: x['SHOP1'] + x['SHOP2'], axis=1)
# => CPU times: user 1.11 ms, sys: 57 µs, total: 1.17 ms
# Wall time: 1.15 ms</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlightTabs-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div></div><p>Разница в производительности больше в два раза. Векторизованные функции более производительны. Но функционал векторизованных функций ограничен. При этом с помощью метода <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code> можно выполнять сложные преобразования.</p>
<h3 id="heading-3-5">Векторные арифметические операции</h3>
<p>Над столбцами можно выполнять основные арифметические операции. Выше был пример операции сложений. Ниже случаи для других операций:</p>
<div class="m_5cb1b9c8 mantine-CodeHighlightTabs-root"><div style="--sa-corner-width:0px;--sa-corner-height:0px" class="m_7b14120b mantine-CodeHighlightTabs-filesScrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><div class="m_38d99e51 mantine-CodeHighlightTabs-files"><button class="mantine-focus-auto m_5cac2e62 mantine-CodeHighlightTabs-file m_87cf2631 mantine-UnstyledButton-root" data-active="true" type="button"><span>python</span></button><button class="mantine-focus-auto m_5cac2e62 mantine-CodeHighlightTabs-file m_87cf2631 mantine-UnstyledButton-root" type="button"><span>python</span></button></div></div></div><div data-orientation="horizontal" class="m_c44ba933 mantine-ScrollArea-scrollbar" data-hidden="true" style="position:absolute;--sa-thumb-width:18px" data-mantine-scrollbar="true"></div><div class="m_c44ba933 mantine-ScrollArea-scrollbar" data-hidden="true" data-orientation="vertical" style="position:absolute;--sa-thumb-height:18px" data-mantine-scrollbar="true"></div></div><div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlightTabs-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlightTabs-controls" data-with-offset="true"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlightTabs-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlightTabs-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlightTabs-pre" data-with-offset="true"><code class="m_5caae6d3 mantine-CodeHighlightTabs-code">df_clicks['MULTIPLE'] = df_clicks['SHOP1'] * df_clicks['SHOP2']
print(df_clicks[['SHOP1', 'SHOP2', 'MULTIPLE']].head())
# => SHOP1 SHOP2 MULTIPLE
# day
# 1 319.0 -265.0 -84535.0
# 2 292.0 274.0 80008.0
# 3 283.0 301.0 85183.0
# 4 328.0 364.0 119392.0
# 5 391.0 355.0 138805.0</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlightTabs-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div></div><p>Из примеров видно, что арифметические операции можно выполнять как между столбцами, так и между столбцом и другим объектом, например, числом. Этот прием называется укладыванием. Он также позволяет выполнять операции быстрее, чем проход по элементам в цикле.</p>
<h3 id="heading-3-6">Изменение типов данных</h3>
<p>Тип столбцов важен для <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">DataFrame</code>. От него зависит корректность проведения тех или иных операций. Иногда его приходится изменять.</p>
<p>Предположим, что нам в каких-то целях необходимо поработать с числовым столбцом, как со строковыми данными. Это можно легко сделать с помощью метода <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">astype()</code>:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">print(df_clicks[['SHOP1', 'SHOP2']].info())
# => <class 'pandas.core.frame.DataFrame'>
# Int64Index: 28 entries, 1 to 28
# Data columns (total 2 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 SHOP1 28 non-null float64
# 1 SHOP2 27 non-null float64
# dtypes: float64(2)
# memory usage: 1.7 KB</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Преобразуем тип для <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">SHOP1</code>:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">df_clicks['SHOP1'] = df_clicks['SHOP1'].astype(str)
print(df_clicks[['SHOP1', 'SHOP2']].info())
# => <class 'pandas.core.frame.DataFrame'>
# Int64Index: 28 entries, 1 to 28
# Data columns (total 2 columns):
# # Column Non-Null Count Dtype
# --- ------ -------------- -----
# 0 SHOP1 28 non-null object
# 1 SHOP2 27 non-null float64
# dtypes: float64(1), object(1)
# memory usage: 1.7+ KB</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Метод <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">astype()</code> ожидает на вход тип объекта, к которому необходимо привести элементы столбца.</p>
<h3 id="heading-3-7">Замена элементов согласно словарю</h3>
<p>Существуют преобразования данных в столбцах <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">DataFrame</code>, которые требуют заменить одно значение на другое. Если подстановку значений можно задать с помощью словаря, то достаточно воспользоваться методом <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">map()</code>.</p>
<p>Допустим, 150 кликов и более — это хорошо, а меньше — это плохо. Добавим столбец с категорией значений 0 и 1 согласно данному условию:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">df_clicks['GOOD_OR_BAD'] = df_clicks['SHOP2'].apply(lambda x: 0 if x < 150 else 1)
print(df_clicks[['SHOP2', 'GOOD_OR_BAD']].head())
# => SHOP2 GOOD_OR_BAD
# day
# 1 -315.0 0
# 2 174.0 1
# 3 201.0 1
# 4 264.0 1
# 5 255.0 1</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Создадим словарь, согласно которому будет выполняться замена:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">map_dict = {0:'BAD', 1:'GOOD'}</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<p>Заменим значения столбца <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">GOOD_OR_BAD</code>:</p>
<div style="margin-bottom:var(--mantine-spacing-lg)" class="m_e597c321 mantine-CodeHighlight-codeHighlight" dir="ltr"><div class="m_be7e9c9c mantine-CodeHighlight-controls"><button style="--ai-bg:transparent;--ai-hover:transparent;--ai-color:inherit;--ai-bd:none" class="mantine-focus-auto mantine-active m_d498bab7 mantine-CodeHighlight-control m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="none" type="button" aria-label="Copy code"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" stroke-width="2" stroke="currentColor" fill="none" stroke-linecap="round" stroke-linejoin="round"><path stroke="none" d="M0 0h24v24H0z" fill="none"></path><path d="M8 8m0 2a2 2 0 0 1 2 -2h8a2 2 0 0 1 2 2v8a2 2 0 0 1 -2 2h-8a2 2 0 0 1 -2 -2z"></path><path d="M16 8v-2a2 2 0 0 0 -2 -2h-8a2 2 0 0 0 -2 2v8a2 2 0 0 0 2 2h2"></path></svg></span></button></div><div style="--scrollarea-scrollbar-size:calc(0.25rem * var(--mantine-scale));--sa-corner-width:0px;--sa-corner-height:0px" class="m_f744fd40 mantine-CodeHighlight-scrollarea m_d57069b5 mantine-ScrollArea-root" dir="ltr"><div style="overflow-x:hidden;overflow-y:hidden;overscroll-behavior-inline:none" class="m_c0783ff9 mantine-ScrollArea-viewport" data-scrollbars="xy"><div class="m_b1336c6 mantine-ScrollArea-content"><pre class="m_2c47c4fd mantine-CodeHighlight-pre" style="padding:0"><code class="m_5caae6d3 mantine-CodeHighlight-code">df_clicks['GOOD_OR_BAD'] = df_clicks['GOOD_OR_BAD'].map(map_dict)
print(df_clicks[['SHOP2','GOOD_OR_BAD']].head())
# => SHOP2 GOOD_OR_BAD
# day
# 1 -315.0 BAD
# 2 174.0 GOOD
# 3 201.0 GOOD
# 4 264.0 GOOD
# 5 255.0 GOOD</code></pre></div></div></div><button class="mantine-focus-auto m_c9378bc2 mantine-CodeHighlight-showCodeButton m_87cf2631 mantine-UnstyledButton-root" data-hidden="true" type="button">Expand code</button></div>
<h2 id="heading-2-8">Выводы</h2>
<p>В этом уроке мы познакомились с несколькими способами преобразования строк и столбцов объекта <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">DataFrame</code> библиотеки Pandas.
Обычно выделяют два подхода:</p>
<ul>
<li>Использование метода <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code></li>
<li>Применение векторизованных функций</li>
</ul>
<p>В случае использования метода <code style="margin-bottom:var(--mantine-spacing-lg)" class="m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight m_e597c321 mantine-CodeHighlight-codeHighlight m_dfe9c588 mantine-InlineCodeHighlight-inlineCodeHighlight">apply()</code> можно выполнять сложное преобразование, но вычисления будут сравнительно долгими. В случае векторизованных функций все наоборот — получаем высокую производительность, но ограниченный функционал. Обычно аналитики делают свой выбор в зависимости от условий задачи.</p></div><div style="margin-block:var(--mantine-spacing-xl)" class=""><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md)" class="m_8a5d1357 mantine-Title-root" data-order="2">Рекомендуемые программы</h2><style data-mantine-styles="inline">.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xs);--carousel-slide-size:70%;}@media(min-width: 36em){.__m__-_R_2mremqrdub_{--carousel-slide-gap:var(--mantine-spacing-xl);--carousel-slide-size:50%;}}</style><div style="--carousel-control-size:calc(2.5rem * var(--mantine-scale));--carousel-controls-offset:var(--mantine-spacing-sm);margin-bottom:var(--mantine-spacing-lg);padding-block:var(--mantine-spacing-sm);background:var(--app-color-surface)" class="m_17884d0f mantine-Carousel-root responsiveClassName" data-orientation="horizontal" data-include-gap-in-size="true"><div class="m_39bc3463 mantine-Carousel-controls" data-orientation="horizontal"><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="previous" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button><button class="mantine-focus-auto m_64f58e10 mantine-Carousel-control m_87cf2631 mantine-UnstyledButton-root" type="button" data-inactive="true" data-type="next" tabindex="-1"><svg viewBox="0 0 15 15" fill="none" xmlns="http://www.w3.org/2000/svg" style="transform:rotate(-90deg);width:calc(1rem * var(--mantine-scale));height:calc(1rem * var(--mantine-scale));display:block"><path d="M3.13523 6.15803C3.3241 5.95657 3.64052 5.94637 3.84197 6.13523L7.5 9.56464L11.158 6.13523C11.3595 5.94637 11.6759 5.95657 11.8648 6.15803C12.0536 6.35949 12.0434 6.67591 11.842 6.86477L7.84197 10.6148C7.64964 10.7951 7.35036 10.7951 7.15803 10.6148L3.15803 6.86477C2.95657 6.67591 2.94637 6.35949 3.13523 6.15803Z" fill="currentColor" fill-rule="evenodd" clip-rule="evenodd"></path></svg></button></div><div class="m_a2dae653 mantine-Carousel-viewport" data-type="media"><div class="m_fcd81474 mantine-Carousel-container __m__-_R_2mremqrdub_" data-orientation="horizontal"><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/data-analytics?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">7 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Аналитик данных</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите SQL, Python, Pandas, Tableau, Superset и методы A/B-тестов.</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6MzY1MywicHVyIjoiYmxvYl9pZCJ9fQ==--5107185de77b3481e0a836f9fc7326c4e1b77be4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Data%20extraction-pana.png" alt="Аналитик данных" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 4 395 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/python-for-data-analysts?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">3 месяца</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Python для анализа данных</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите Python для больших данных и аналитических задач</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6Mzk1OSwicHVyIjoiYmxvYl9pZCJ9fQ==--39f076671bc03debdf48e861bbd4c34c3fd4aac8/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Data%20extraction-bro.png" alt="Python для анализа данных" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 3 900 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/bi-analyst?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">7 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">BI-аналитик</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите SQL, BI-инструменты и визуализацию данных</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDg3MSwicHVyIjoiYmxvYl9pZCJ9fQ==--8175585f43b5401994e29b3ae73d76963d942512/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Browser%20stats-bro.png" alt="BI-аналитик" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 4 395 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/programs/product-analyst?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card" target="_blank"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><div style="--group-gap:calc(0.25rem * var(--mantine-scale));--group-align:center;--group-justify:flex-start;--group-wrap:nowrap" class="m_4081bf90 mantine-Group-root"><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">7 месяцев</span><span class="mantine-focus-auto m_b6d8b162 mantine-Text-root">·</span><span style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">С нуля</span></div><p style="margin-bottom:var(--mantine-spacing-sm);font-size:var(--mantine-font-size-h5);font-weight:bold" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Продуктовый аналитик</p><p class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Изучите продуктовые метрики, A/B-тесты и анализ пользовательских данных</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="https://hexlet.io/rails/active_storage/representations/proxy/eyJfcmFpbHMiOnsiZGF0YSI6NDg2MiwicHVyIjoiYmxvYl9pZCJ9fQ==--04a703ca18d7bf689064f1f3c2721058bd5564e4/eyJfcmFpbHMiOnsiZGF0YSI6eyJmb3JtYXQiOiJ3ZWJwIiwicmVzaXplX3RvX2xpbWl0IjpbNDAwLDQwMF0sInNhdmVyIjp7InF1YWxpdHkiOjg1fX0sInB1ciI6InZhcmlhdGlvbiJ9fQ==--5b6f46dacd1af664f27558553a58076185091823/Statistics-bro.png" alt="Продуктовый аналитик" loading="eager"/></div><div style="--group-gap:var(--mantine-spacing-md);--group-align:end;--group-justify:space-between;--group-wrap:wrap;margin-top:var(--mantine-spacing-xs)" class="m_4081bf90 mantine-Group-root"><p style="font-size:var(--mantine-font-size-xl)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">от 4 395 ₽</p><p style="font-size:var(--mantine-font-size-sm)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Посмотреть →</p></div></div></div></a></div></div><div class="m_d98df724 mantine-Carousel-slide" data-orientation="horizontal"><div tabindex="0" style="cursor:pointer;height:100%"><a style="text-decoration:none" class="mantine-focus-auto m_849cf0da m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses?promo_name=programs_list&promo_position=course&promo_creative=catalog_card&promo_type=card"><div style="height:100%" class="m_e615b15f mantine-Card-root m_1b7284a3 mantine-Paper-root" data-with-border="true"><h2 style="--title-fw:var(--mantine-h2-font-weight);--title-lh:var(--mantine-h2-line-height);--title-fz:var(--mantine-h2-font-size);margin-bottom:var(--mantine-spacing-md);font-size:var(--mantine-font-size-h3)" class="m_8a5d1357 mantine-Title-root" data-order="2" data-responsive="true">Каталог</h2><p style="margin-bottom:auto" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Полный список доступных курсов по разным направлениям</p><div style="margin-top:auto" class=""><div class="m_4451eb3a mantine-Center-root"><img style="opacity:0.8;width:70%" class="m_9e117634 mantine-Image-root mantine-visible-from-xs" src="/vite/assets/development-BVihs_d5.png" alt="Orientation"/></div></div></div></a></div></div></div></div></div></div></div></div></div><style data-mantine-styles="inline">.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:8.333333333333334%;--col-max-width:8.333333333333334%;}@media(min-width: 48em){.__m__-_R_1bdub_{--col-flex-grow:auto;--col-flex-basis:16.666666666666668%;--col-max-width:16.666666666666668%;}}</style><div style="min-width:0rem;height:100%;min-height:0rem" class="m_96bdd299 mantine-Grid-col __m__-_R_1bdub_"><div style="margin-inline:var(--mantine-spacing-xs)" class="mantine-visible-from-sm"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-lg);text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/python-pandas/lessons/pandas-column-functions/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label"><span style="margin-inline-end:var(--mantine-spacing-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Дальше</span>→</span></span></a><a style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Навигация по теме</span><span class="m_57492dcc mantine-NavLink-description">Теория</span></div><span class="m_690090b5 mantine-NavLink-section" data-position="right"></span></a><div style="margin-block:var(--mantine-spacing-lg)" class="m_3eebeb36 mantine-Divider-root" data-orientation="horizontal" role="separator"></div><div style="margin-block:var(--mantine-spacing-lg)" class=""><div style="justify-content:space-between;margin-bottom:calc(0.1875rem * var(--mantine-scale));color:var(--mantine-color-dimmed);font-size:var(--mantine-font-size-xs)" class="m_8bffd616 mantine-Flex-root __m__-_R_qimrbdub_"><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">Завершено</p><p style="font-size:var(--mantine-font-size-xs)" class="mantine-focus-auto m_b6d8b162 mantine-Text-root">0 / 10</p></div><div style="--progress-size:var(--progress-size-sm)" class="m_db6d6462 mantine-Progress-root" data-size="sm"><div style="--progress-section-size:0%;--progress-section-color:var(--mantine-color-gray-filled)" class="m_2242eb65 mantine-Progress-section" role="progressbar" aria-valuemax="100" aria-valuemin="0" aria-valuenow="0" aria-valuetext="0%"></div></div></div><button style="padding-inline:0rem" class="mantine-focus-auto m_f0824112 mantine-NavLink-root m_87cf2631 mantine-UnstyledButton-root" type="button"><span class="m_690090b5 mantine-NavLink-section" data-position="left"><div style="--ti-size:var(--ti-size-sm);--ti-bg:transparent;--ti-color:var(--mantine-color-indigo-light-color);--ti-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;color:inherit" class="m_7341320d mantine-ThemeIcon-root" data-variant="transparent" data-size="sm"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></div></span><div class="m_f07af9d2 mantine-NavLink-body"><span class="m_1f6ac4c4 mantine-NavLink-label">Обсуждения (архив)</span><span class="m_57492dcc mantine-NavLink-description"></span></div></button><div style="--toc-bg:var(--mantine-color-blue-light);--toc-color:var(--mantine-color-blue-light-color);--toc-size:var(--mantine-font-size-sm);--toc-radius:var(--mantine-radius-sm);margin-top:var(--mantine-spacing-xl)" class="m_bcaa9990 mantine-TableOfContents-root" data-variant="light" data-size="sm"></div></div><div class="mantine-hidden-from-sm"><div style="--stack-gap:0rem;--stack-align:stretch;--stack-justify:flex-start" class="m_6d731127 mantine-Stack-root"><a style="--button-color:var(--mantine-color-white);margin-bottom:var(--mantine-spacing-xs);padding:0rem;text-decoration:none" class="mantine-focus-auto m_849cf0da mantine-focus-auto m_77c9d27d mantine-Button-root m_87cf2631 mantine-UnstyledButton-root m_b6d8b162 mantine-Text-root mantine-Anchor-root" data-underline="hover" href="/courses/python-pandas/lessons/pandas-column-functions/finish_unit?unit=theory" data-disabled="true" data-block="true" disabled=""><span class="m_80f1301b mantine-Button-inner"><span class="m_811560b9 mantine-Button-label">→</span></span></a><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" data-disabled="true" type="button" disabled=""><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-list-numbers "><path d="M11 6h9"></path><path d="M11 12h9"></path><path d="M12 18h8"></path><path d="M4 16a2 2 0 1 1 4 0c0 .591 -.5 1 -1 1.5l-3 2.5h4"></path><path d="M6 10v-6l-2 2"></path></svg></span></button><button style="--ai-size:var(--ai-size-sm);--ai-bg:transparent;--ai-hover:var(--mantine-color-indigo-light-hover);--ai-color:var(--mantine-color-indigo-light-color);--ai-bd:calc(0.0625rem * var(--mantine-scale)) solid transparent;padding-block:var(--mantine-spacing-lg);color:inherit;width:100%" class="mantine-focus-auto mantine-active m_8d3f4000 mantine-ActionIcon-root m_87cf2631 mantine-UnstyledButton-root" data-variant="subtle" data-size="sm" type="button"><span class="m_8d3afb97 mantine-ActionIcon-icon"><svg xmlns="http://www.w3.org/2000/svg" width="24" height="24" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.2" stroke-linecap="round" stroke-linejoin="round" class="tabler-icon tabler-icon-message "><path d="M8 9h8"></path><path d="M8 13h6"></path><path d="M18 4a3 3 0 0 1 3 3v8a3 3 0 0 1 -3 3h-5l-5 3v-3h-2a3 3 0 0 1 -3 -3v-8a3 3 0 0 1 3 -3h12"></path></svg></span></button></div></div></div></div></div></div></div>
</main>
<footer class="bg-dark fw-light text-light px-3 py-5">
<div class="row small">
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 mb-3">Хекслет</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/about">О нас</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/testimonials">Отзывы</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://b2b.hexlet.io" role="button">Корпоративное обучение</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/blog">Блог</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/qna">Вопросы и ответы</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/glossary">Глоссарий</a>
</li>
<li>
<span class="nav-link link-light py-1 ps-0 external-link" data-href="https://help.hexlet.io" data-target="_blank" role="button">Справка</span>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" target="_blank" rel="noopener noreferrer" href="/map">Карта сайта</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5 fw-normal mb-3">Направления</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_devops">DevOps
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_data_analytics">Аналитика
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_backend_development">Бэкенд
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_programming">Программирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_testing">Тестирование
</a></li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/courses_front_end_dev">Фронтенд
</a></li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Профессии</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/devops-engineer-from-scratch">DevOps-инженер с нуля</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/go">Go-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/java">Java-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python">Python-разработчик </a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/data-analytics">Аналитик данных</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/qa-engineer">Инженер по ручному тестированию</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php">РНР-разработчик</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/frontend">Фронтенд-разработчик</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-6 col-md-3">
<div class="h5">Навыки</div>
<ul class="list-unstyled">
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/python-django-developer">Django</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/docker">Docker</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/php-laravel-developer">Laravel</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/postman">Postman</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-react-developer">React</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/js-rest-api">REST API в Node.js</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/spring-boot">Spring Boot</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/programs/typescript">Typescript</a>
</li>
</ul>
</div>
</div>
<hr>
<div class="row">
<div class="col-12 col-sm-4 col-md-2">
<div class="fs-4">
<ul class="list-unstyled d-flex">
<li class="me-3">
<a aria-label="Telegram" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://t.me/hexlet_ru"><span class="bi bi-telegram"></span>
</a></li>
<li>
<a aria-label="Youtube" target="_blank" class="link-light" rel="noopener noreferrer nofollow" href="https://www.youtube.com/user/HexletUniversity"><span class="bi bi-youtube"></span>
</a></li>
</ul>
</div>
<div class="mb-2 d-flex flex-column">
<a class="link-light text-decoration-none" rel="nofollow" href="mailto:support@hexlet.io">support@hexlet.io</a>
<a class="link-light text-decoration-none py-2" target="_blank" href="https://t.me/hexlet_help_bot">t.me/hexlet_help_bot</a>
</div>
<ul class="list-unstyled d-flex">
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://hexlet.io/locale/switch?new_locale=en" data-target="_self" role="button"><span class="my-auto">EN</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 opacity-100 external-link" rel="nofollow" data-href="https://ru.hexlet.io/locale/switch?new_locale=ru" data-target="_self" role="button"><span class="my-auto">RU</span>
</span></li>
<li class="me-3">
<span class="link-light text-decoration-none opacity-50 x-font-size-18 external-link" rel="nofollow" data-href="https://kz.hexlet.io/locale/switch?new_locale=kz" data-target="_self" role="button"><span class="my-auto">KZ</span>
</span></li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<ul class="list-unstyled fs-4">
<li class="mb-3">
<a class="link-light text-decoration-none" href="tel:8%20800%20100%2022%2047">8 800 100 22 47</a>
<span class="d-block opacity-50 small">бесплатно по РФ</span>
</li>
<li>
<a class="link-light text-decoration-none" href="tel:%2B7%20495%20085%2021%2062">+7 495 085 21 62</a>
<span class="d-block opacity-50 small">бесплатно по Москве</span>
</li>
</ul>
</div>
<div class="col-12 col-sm-4 col-md-3">
<div class="small mb-3">Образовательные услуги оказываются на основании Л035-01298-77/01989008 от 14.03.2025</div>
<ul class="list-unstyled small">
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/legal">Правовая информация</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/offer">Оферта</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/license">Лицензия</a>
</li>
<li>
<a class="nav-link link-light py-1 ps-0" href="/pages/contacts">Контакты</a>
</li>
</ul>
</div>
<div class="col-12 col-sm-12 col-md-4 small">
<div class="mb-2">
<div>ООО «<a href="/" class="text-decoration-none link-light">Хекслет Рус</a>»</div>
<div>108813 г. Москва, вн.тер.г. поселение Московский,</div>
<div>г. Московский, ул. Солнечная, д. 3А, стр. 1, помещ. 20Б/3</div>
<div>ОГРН 1217300010476</div>
<div>ИНН 7325174845</div>
</div>
<hr>
<div>АНО ДПО «<a href="/" class="text-decoration-none link-light">Учебный центр «Хекслет</a>»</div>
<div>119331 г. Москва, вн. тер. г. муниципальный округ</div>
<div>Ломоносовский, пр-кт Вернадского, д. 29</div>
<div>ОГРН 1247700712390</div>
<div>ИНН 7736364948</div>
</div>
</div>
</footer>
<div id="root-assistant-offcanvas"></div>
<script src="/vite/assets/assistant-Bukl1lYy.js" crossorigin="anonymous" type="module"></script><link rel="modulepreload" href="/vite/assets/chunk-DsPFFUou.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/init-BrRXra1y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/ErrorFallbackBlock-naDSYSy9.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/MarkdownBlock-DbyKWoR_.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/gon-D3e4yh1x.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/mantine-CGMYrt2Y.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/shiki-V011pkdv.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/utils-DRqSHbQE.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/routes-CCH8ilKF.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-XR8Qr8kR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dist-GCHh59xr.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/Box-B5-OOzBf.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/notifications.store-C-3AFSMn.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useIsomorphicEffect-HJ6VK0D3.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/lib-KSp6QbZ0.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/axios-BEvgo0ym.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/classnames-l6ipYlLR.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/dayjs.min-BkKovM-s.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/debounce-jMQ_Cf4f.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/i18next-BlSq9s7B.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/client-U9M77rxp.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-dom-DaLxUz_h.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/useTranslation-Bx1Cdrkz.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/compiler-runtime-6XxiPFnt.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/jsx-runtime-CwjcCKJi.js" as="script" crossorigin="anonymous">
<link rel="modulepreload" href="/vite/assets/react-CkL4ZRHB.js" as="script" crossorigin="anonymous">
<script defer src="https://static.cloudflareinsights.com/beacon.min.js/v67327c56f0bb4ef8b305cae61679db8f1769101564043" integrity="sha512-rdcWY47ByXd76cbCFzznIcEaCN71jqkWBBqlwhF1SY7KubdLKZiEGeP7AyieKZlGP9hbY/MhGrwXzJC/HulNyg==" data-cf-beacon='{"version":"2024.11.0","token":"d11015b65d11429ea6b4a2ef37dd7e0b","server_timing":{"name":{"cfCacheStatus":true,"cfEdge":true,"cfExtPri":true,"cfL4":true,"cfOrigin":true,"cfSpeedBrain":true},"location_startswith":null}}' crossorigin="anonymous"></script>
</body>
</html>