Към съдържанието
wannacode

Широко и дълго: pivot_table и melt

Накратко: pivot_table прави широка таблица с колона за всяка категория, а melt връща дългата с ред за всеки факт; формата се избира според въпроса.

Проблем

„Дай ми го по месеци и категории“

Управителят иска оборота за годината в една таблица: месеците надолу, категориите надясно, както в Excel. Знаеш как: слепваш редовете с поръчките, продуктите и категориите (merge) и групираш по два ключа. Отказаните поръчки не са оборот, затова ги махаш. Подаръчната карта е без категория и получава свое име, иначе ще изпадне от групите:

Pythonданни: таблиците на магазина

Числата са верни, но са 84 реда: 12 месеца по 7 категории, един под друг. За да сравниш януари с юли, търсиш с очи из списъка. Таблицата, която управителят иска, е 12 реда и 7 колони със същите 84 числа.

Месецът тук е номерът му: 1 е януари 2026, а 11 и 12 са ноември и декември 2025.

Идеята

Дълго и широко

Едни и същи числа могат да стоят в две форми:

  • Дълга (long): ред за всеки факт. Колоните са month, category и revenue, и всяка двойка месец–категория е отделен ред.
  • Широка (wide): ред за всеки месец и колона за всяка категория. Категорията вече не е колона: стойностите ѝ са станали имена на колони.

От дълга към широка с резултата на groupby е един ред: unstack() взима последното ниво на индекса (категорията) и го прави колони:

Pythonданни: таблиците на магазина

Формата е (12, 7): 12 месеца и 7 категории. Януари: 593 € кухня, 2 038 € млечни, 1 225 € напитки.

Идеята

Направо широко: pivot_table

pivot_table прави групирането и подредбата наведнъж. Казваш му четири неща:

  • index: какво е в редовете (месецът);
  • columns: какво става колони (категорията);
  • values: коя колона смята (оборотът);
  • aggfunc: как смята ('sum').
Pythonданни: таблиците на магазина

Сега се чете с поглед. Декември е пикът: кухнята прави 3 241 €, над 4 пъти повече от обикновен месец, а подаръчната карта 2 160 €. Лятото носи напитките и плодовете: напитките са 1 756 € през юли срещу 1 225 € през януари. Септември е слаб почти навсякъде. Защо, ще разберем в проекта.

По-точно, за любопитните

Има и pivot без „table“: той само подрежда и не смята. Ако двойка месец–категория се среща в повече от един ред, pivot спира с грешка, а pivot_table ги събира с aggfunc. За сурови редове ти трябва pivot_table.

Пробвай

Бройките по категории

Колко броя е продала всяка категория всеки месец? Запиши в units таблица с категориите в редовете и месеците в колоните.

Pythonданни: таблиците на магазина

Идеята

Празните клетки: fill_value

В широката таблица всяка двойка има клетка, дори когато в данните няма такава двойка. Ето колко е купил всеки клиент от всяка категория в 60-те поръчки:

Pythonданни: таблиците на магазина

35 клетки са NaN. Клиент 3 не е купувал напитки, почистване и хляб. Тук празното значи „нула покупки“, а не „не знаем“. Затова е вярно да го смениш с нула: fill_value=0.

Pythonданни: таблиците на магазина

Това е случаят от урока за обобщенията, в който 0 е правилна замяна: нулата наистина значи нула. Ако клетката беше празна, защото отчетът липсва, нулата щеше да лъже.

Идеята

Сборовете: margins

margins=True добавя ред и колона All със сборовете. Тук са показани две от категориите и общото:

Pythonданни: таблиците на магазина

Колоната All е оборотът за месеца, а редът All е оборотът на категорията за годината: 11 304 € кухня, 17 811 € напитки. В ъгъла е общото: 111 186,20 €. Септември е 7 129 €, по-малко от август (8 813 €) и октомври (9 920 €).

Идеята

Обратно към дълго: melt

Управителят праща плана за следващите три месеца. Таблицата е от Excel и е широка: по ред за категория и по колона за месец.

Широката таблица е удобна за четене, но не и за смятане. Месецът не е колона, а е в имената на колоните, и няма по какво да групираш. melt я разтапя обратно в дълга: id_vars е колоната, която остава, var_name кръщава колоната с имената на старите колони, а value_name колоната с числата:

Pythonданни: таблиците на магазина

От 7 реда и 4 колони стават 21 реда и 3 колони: всяко число от плана е отделен ред. Сега месецът е колона и groupby работи:

Pythonданни: таблиците на магазина

Планът за декември е 16 650 €, а за ноември 9 700 €.

Пробвай

Коя форма за какво

1. Имаш дълга таблица plan_long с колони category, month и plan. Как смяташ плана за всеки месец?
2. Искаш линия за всяка категория по месеци с df.plot(), което рисува по линия за всяка колона. Каква таблица му даваш?

Упражнение

Отчетът за управителя

Направи отчета от първата карта: report с оборота по месеци (редове) и категории (колони), със сборовете All. После запиши в dec_share каква част от оборота за годината е декември.

Pythonданни: таблиците на магазина

Колко е планът за трите месеца общо за всяка категория? Направи plan дълга (plan_long с колони category, month и plan) и запиши в per_category сбора за всяка категория.

Pythonданни: таблиците на магазина

Тест

Провери се

1. Какво смята pivot_table, ако не кажеш aggfunc?
2. В таблицата „клиент × категория“ клиент 3 няма покупки от напитки и там стои NaN. Кога е вярно fill_value=0?
3. Таблица от Excel има колони category, 2026-11, 2026-12 и 2027-01. Кое я прави дълга?
4. Какво добавя margins=True?

Създаден от Иво Гергов като част от кампанията на Evo Tech за достъпно обучение по програмиране ·