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

Series и DataFrame

Накратко: В pandas Series е колона с етикети, а DataFrame е таблица от такива колони; индексът носи имената на редовете и подравнява сметките по тях.

Проблем

„Колко пари стоят на склада?“

Управителят пита колко струва стоката на склада. Отговорът е цена по наличност за всеки продукт и после сбор. После ще иска да види числото на отделен продукт, по име.

С NumPy вече можеш да го сметнеш. Но в урока за обобщенията argmax върна 22, позиция, и името трябваше да вземеш от отделен масив names. Ако подредиш единия масив, а другия забравиш, имената и числата се разминават и никой не забелязва.

pandas държи до всяко число етикет: кой продукт е. В този урок ще видиш как.

Идеята

Колона с етикети: Series

Series е масив на NumPy с етикет до всяка стойност. Етикетите се казват индекс. Ето три цени с имената на продуктите като индекс:

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

prices['Сирене'] дава 7.9: стойността се взима по етикет, а не по място. prices.index показва етикетите, а to_numpy() дава голите числа като масив.

Идеята

Таблица от колони: DataFrame

DataFrame е няколко Series с общ индекс, една до друга. Всяка колона има име и свой тип. Видя го в първия поглед, сега го виж по части:

Pythonданни: таблиците на магазина
  • columns са имената на колоните: 6 на брой.
  • index е RangeIndex от 0 до 24: read_csv номерира редовете от 0, щом не му кажеш друго. Колоната id е отделно нещо и започва от 1.
  • dtypes е типът на всяка колона. int64 и float64 са числа, str е текст.

Виж го

Колоната е Series

Взимаш колона с името ѝ в квадратни скоби, както в първия поглед. Резултатът е Series:

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

Отляво е индексът на таблицата (0, 1, 2), а отдолу е името на колоната (Name: price) и типът. Всичко, което можеш с Series, можеш и с всяка колона.

1. Какво е products['stock']?

Идеята

Имената в индекса: set_index

Номерата от 0 до 24 не казват нищо на управителя. set_index('name') прави колоната name индекс: имената на продуктите стават етикетите на редовете.

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

Сега наличността на кафето е by_name['stock']['Кафе на зърна']: 15 пакета. А най-скъпият продукт е отговор с име:

  • argmax() пак дава позицията: 22.
  • idxmax() дава етикета на най-голямата стойност: „Комплект ножове“. Има и idxmin().

Етикетите вървят с числата: каквото и да правиш със Series, името си остава до цената.

Идеята

И обратно: reset_index

set_index не променя products, а връща нова таблица. Колоната name в нея вече е индекс, затова колоните са 5 вместо 6. reset_index() връща индекса като обикновена колона и номерира редовете отново от 0:

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

Кое да е индексът, решаваш според въпроса. За „по име“ слагаш имената, а за нормална таблица, която ще пишеш във файл, ги връщаш в колона.

Пробвай

Най-евтиният продукт

Кой е най-евтиният продукт? Сложи имената в индекса (by_name), а в cheapest запиши името на продукта с най-малката цена.

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

Виж го

Индексът подрежда сметките

Доставчикът праща нов ценови лист. Продуктите са същите, но в друг ред. С масиви на NumPy ще извадиш първото от първото, второто от второто. Със Series pandas вади стойностите с еднакъв етикет, където и да са:

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

Със Series кафето е поскъпнало с 1 €, хлябът с 0,10 €, а сиренето с 0,50 €. С масивите първото число е 13,70 €: новата цена на кафето минус старата цена на хляба. Последното е -12,30 €: млякото минус кафето. Числата изглеждат напълно сериозно и са грешни.

Това се казва подравняване по индекс (alignment). Резултатът е подреден по етикети, по азбучен ред.

Виж го

Етикет, който го няма

Ако етикетът е само в едната Series, pandas няма с какво да го сметне:

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

Сиренето е само в тази седмица, затова разликата за него е NaN. Това е честно: не знаем колко сирене сме продали миналата седмица. Видя в обобщенията, че липсата не е нула, и pandas го спазва.

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

Ако знаеш, че липсата значи нула (продукт, който миналата седмица не сме продавали), кажи го изрично: this_week.sub(last_week, fill_value=0). Така решението е видимо в кода, а не скрито. Подравняването важи за +, -, *, / и за сравненията между две Series.

Пробвай

Какво поскъпна

Двата ценови листа са в различен ред. Запиши в change с колко се е променила цената на всеки продукт (новата минус старата), закръглено до 2 знака, с имената на продуктите в индекса.

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

Упражнение

Стоката на склада

Отговори на управителя. Сложи имената на продуктите в индекса. В stock_value запиши стойността на наличността на всеки продукт (цена по наличност), в total сбора ѝ, а в real_total сбора без подаръчната карта, закръглен до 2 знака.

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

Тест

Провери се

1. Таблицата products е прочетена с read_csv. Какво е products.index?
2. След by_name = products.set_index('name') какво дават by_name['price'].argmax() и by_name['price'].idxmax()?
3. Седмицата this_week има Сирене, а last_week няма. Какво е (this_week - last_week)['Сирене']?
4. Два ценови листа са Series с имената на продуктите, но в различен ред. Защо new.to_numpy() - old.to_numpy() е опасно?

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