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

Филтри и подреждане

Накратко: Филтрирането в pandas пази само редовете, за които маската е True (или isin, between, query), а sort_values ги подрежда по колона.

Проблем

Списъкът за доставчика

Доставчикът на храни идва утре. Управителят иска списък: храните, от които имаме по-малко от 20 броя, като най-спешните са първи. После пита и за поръчките през годината: колко са отказани и колко клиенти ни купуват редовно.

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

25 продукта можеш да прегледаш с очи. Поръчките за годината са 11 116, и там очите не стигат. Трябва ти начин да кажеш на таблицата „дай ми само тези редове“ и „подреди ги така“.

Идеята

Маска върху таблица

Маската от NumPy работи и в pandas. products['stock'] < 20 сравнява всеки ред и дава колона (Series) от True и False, с индекса на таблицата. Сложена в квадратни скоби, маската оставя редовете с True:

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

low.sum() брои истините: 9 продукта са под 20 броя. Това се казва филтър: таблица само с редовете, за които условието е вярно.

Виж индекса вляво: 3, 6, 7, 12… Редовете пазят етикетите си от products, затова винаги знаеш откъде е дошъл всеки. В [] името на колона избира колона, а маската избира редове.

Идеята

Две условия: &, | и ~

Под 20 броя и под 5 € са две условия заедно. С and става същото като в NumPy:

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

and иска едно True или False, а колоната има 25. Затова и тук пишеш & за „и“, | за „или“ и ~ за „не“, с всяко условие в скоби:

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

Под 20 броя и под 5 € са баницата и краставиците, и двете изчерпани. Под 1 € или над 20 € са кифлата (0,80 €), водата (0,90 €), тиганът (24,90 €) и ножовете (39 €). Подаръчната карта е точно 20 € и не е „над 20“.

Пробвай

Скъпите млечни

Кои млечни продукти (категория 4) струват над 3 €? Запиши таблицата с тях в pricey_dairy.

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

Идеята

От списък и между две числа: isin и between

Храните са в четири категории: 3, 4, 5 и 6. Вместо четири условия с | пишеш isin, което пита „в този списък ли е?“:

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

Храните са 18. С ~ получаваш останалите 7: шестте продукта за дома и подаръчната карта. Картата няма категория (NaN), а NaN не е в никой списък, затова ~ я хваща.

За интервал има between. between(2, 5) е „от 2 до 5 включително“, двата края влизат:

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

Излизат 9 продукта, колкото с (prices >= 2) & (prices <= 5) в урока за NumPy.

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

between(2, 5, inclusive='neither') изключва двата края, а 'left' и 'right' оставят само единия. По подразбиране е 'both'.

Идеята

Текст, който съдържа: str.contains

„Покажи ми всички хлябове.“ В имената има „Бял хляб“ и „Пълнозърнест хляб“, но не можеш да напишеш == 'хляб': никое име не е точно „хляб“. str.contains пита дали текстът се съдържа някъде в името:

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

.str отваря методите за текст на цялата колона. Ще го видиш по-подробно в урока за типовете.

Търсенето различава главни и малки букви. „сирене“ намира само „Баница със сирене“, затова първото число е 1. „Сирене“ е с главно С и не влиза. С case=False буквите не се различават и излизат 2.

Идеята

Условието като текст: query

Дълги маски с products['...'] навсякъде стават трудни за четене. query взима условието като текст, в който имената на колоните стоят сами:

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

В query пишеш and, or и not. Текстът не се смята от Python, а от pandas, и той знае, че става дума за колони. Под 20 броя и над 5 € са 7 продукта.

Променлива от Python влиза с @: category_id in @food е същото като isin(food). Така излизат петте храни под 20 броя, от които ще направиш списъка за доставчика.

1. В limit = 10 е прагът за цената. Кой ред взима продуктите над него?

Идеята

Подреждане: sort_values и nlargest

sort_values('price') подрежда редовете по цена, от малката към голямата. С ascending=False е обратно. За „първите N“ има nlargest(N, колона) и nsmallest:

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

Най-скъпи са ножовете (39 €), тиганът (24,90 €) и подаръчната карта (20 €). nlargest(3, 'price') дава същите три на един ред.

Можеш да подредиш и по няколко колони: първо по категория, а вътре в нея по цена. ascending тогава е списък, по едно за всяка колона. Категориите вървят нагоре, а цените в тях надолу: баницата (2,50 €) е първа в хляба, кашкавалът (9,50 €) в млечните.

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

Подреждането мести редовете, но не им сменя етикетите: индексът в изхода е 22, 21, 24… Ако ти трябват номера 0, 1, 2 в новия ред, добави .reset_index(drop=True).

Идеята

Колко от всяко: value_counts

„Колко поръчки са отказани?“ е въпрос за броене. value_counts брои колко пъти се среща всяка стойност в колона, най-честата отгоре:

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

От 11 116 поръчки за годината 10 254 са доставени, а 657 са отказани. С normalize=True получаваш дял вместо брой: 0,059, тоест 5,9% от поръчките са отказани.

Същото върху номера на клиента казва кой колко пъти е поръчал:

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

Поръчвали са 1 390 клиенти. Най-верният, клиент 1, е поръчал 121 пъти, а 224 клиенти са поръчали само веднъж. Индексът на резултата са номерата на клиентите, а стойностите са броят на поръчките им.

Пробвай

Отворените поръчки

Поръчките със статус new, paid или shipped още не са стигнали до клиента. Запиши таблицата с тях в open_orders.

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

Упражнение

Списъкът и редовните клиенти

Направи списъка за доставчика: храните (категории 3, 4, 5 и 6) с наличност под 20, подредени по наличност от най-малката. При равна наличност по-скъпият продукт е първи. Запиши таблицата в restock.

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

Колко клиенти са поръчали поне 20 пъти през годината? Запиши броя им в regulars.

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

Тест

Провери се

1. Защо във филтъра всяко условие е в скоби: (products["stock"] < 20) & (products["price"] < 5)?
2. Какво дава products["price"].between(2, 5) за продукт, който струва точно 5 €?
3. В food = [3, 4, 5, 6] са храните. Защо ~products["category_id"].isin(food) хваща и подаръчната карта?
4. year["status"].value_counts() върна 5 реда. Как са подредени?

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