Series и DataFrame
Накратко: В pandas Series е колона с етикети, а DataFrame е таблица от такива колони; индексът носи имената на редовете и подравнява сметките по тях.
Проблем
„Колко пари стоят на склада?“
Управителят пита колко струва стоката на склада. Отговорът е цена по наличност за всеки продукт и после сбор. После ще иска да види числото на отделен продукт, по име.
С NumPy вече можеш да го сметнеш. Но в урока за обобщенията argmax върна 22, позиция, и името трябваше да вземеш от отделен масив names. Ако подредиш единия масив, а другия забравиш, имената и числата се разминават и никой не забелязва.
pandas държи до всяко число етикет: кой продукт е. В този урок ще видиш как.
Идеята
Колона с етикети: Series
Series е масив на NumPy с етикет до всяка стойност. Етикетите се казват индекс. Ето три цени с имената на продуктите като индекс:
prices['Сирене'] дава 7.9: стойността се взима по етикет, а не по място. prices.index показва етикетите, а to_numpy() дава голите числа като масив.
Идеята
Таблица от колони: DataFrame
DataFrame е няколко Series с общ индекс, една до друга. Всяка колона има име и свой тип. Видя го в първия поглед, сега го виж по части:
columnsса имената на колоните: 6 на брой.indexеRangeIndexот 0 до 24:read_csvномерира редовете от 0, щом не му кажеш друго. Колонатаidе отделно нещо и започва от 1.dtypesе типът на всяка колона.int64иfloat64са числа,strе текст.
Виж го
Колоната е Series
Взимаш колона с името ѝ в квадратни скоби, както в първия поглед. Резултатът е Series:
Отляво е индексът на таблицата (0, 1, 2), а отдолу е името на колоната (Name: price) и типът. Всичко, което можеш с Series, можеш и с всяка колона.
Идеята
Имената в индекса: set_index
Номерата от 0 до 24 не казват нищо на управителя. set_index('name') прави колоната name индекс: имената на продуктите стават етикетите на редовете.
Сега наличността на кафето е by_name['stock']['Кафе на зърна']: 15 пакета. А най-скъпият продукт е отговор с име:
argmax()пак дава позицията: 22.idxmax()дава етикета на най-голямата стойност: „Комплект ножове“. Има иidxmin().
Етикетите вървят с числата: каквото и да правиш със Series, името си остава до цената.
Идеята
И обратно: reset_index
set_index не променя products, а връща нова таблица. Колоната name в нея вече е индекс, затова колоните са 5 вместо 6. reset_index() връща индекса като обикновена колона и номерира редовете отново от 0:
Кое да е индексът, решаваш според въпроса. За „по име“ слагаш имената, а за нормална таблица, която ще пишеш във файл, ги връщаш в колона.
Пробвай
Най-евтиният продукт
Кой е най-евтиният продукт? Сложи имената в индекса (by_name), а в cheapest запиши името на продукта с най-малката цена.
Решение
import pandas as pd
products = pd.read_csv('products.csv')
by_name = products.set_index('name')
cheapest = by_name['price'].idxmin()
print(cheapest)by_name = products.set_index('name') и cheapest = by_name['price'].idxmin() дава „Кифла с масло“ (0,80 €). argmin() щеше да върне 2: позицията, от която пак трябва да търсиш името. Без set_index и idxmin() дава 2, защото тогава етикетите са номерата на редовете.
Виж го
Индексът подрежда сметките
Доставчикът праща нов ценови лист. Продуктите са същите, но в друг ред. С масиви на NumPy ще извадиш първото от първото, второто от второто. Със Series pandas вади стойностите с еднакъв етикет, където и да са:
Със Series кафето е поскъпнало с 1 €, хлябът с 0,10 €, а сиренето с 0,50 €. С масивите първото число е 13,70 €: новата цена на кафето минус старата цена на хляба. Последното е -12,30 €: млякото минус кафето. Числата изглеждат напълно сериозно и са грешни.
Това се казва подравняване по индекс (alignment). Резултатът е подреден по етикети, по азбучен ред.
Виж го
Етикет, който го няма
Ако етикетът е само в едната Series, pandas няма с какво да го сметне:
Сиренето е само в тази седмица, затова разликата за него е NaN. Това е честно: не знаем колко сирене сме продали миналата седмица. Видя в обобщенията, че липсата не е нула, и pandas го спазва.
По-точно, за любопитните
Ако знаеш, че липсата значи нула (продукт, който миналата седмица не сме продавали), кажи го изрично: this_week.sub(last_week, fill_value=0). Така решението е видимо в кода, а не скрито. Подравняването важи за +, -, *, / и за сравненията между две Series.
Пробвай
Какво поскъпна
Двата ценови листа са в различен ред. Запиши в change с колко се е променила цената на всеки продукт (новата минус старата), закръглено до 2 знака, с имената на продуктите в индекса.
Решение
import pandas as pd
old_prices = pd.Series([1.2, 1.6, 7.9, 13.9], index=['Бял хляб', 'Прясно мляко', 'Сирене', 'Кафе на зърна'])
new_prices = pd.Series([14.9, 1.3, 8.4, 1.6], index=['Кафе на зърна', 'Бял хляб', 'Сирене', 'Прясно мляко'])
change = (new_prices - old_prices).round(2)
print(change)change = (new_prices - old_prices).round(2): pandas намира всеки продукт и в двата листа. Кафето е +1,00 €, сиренето +0,50 €, хлябът +0,10 €, а млякото е без промяна. С to_numpy() числата се вадят по място: първото е 13,70 €, новото кафе минус стария хляб.
Упражнение
Стоката на склада
Отговори на управителя. Сложи имената на продуктите в индекса. В stock_value запиши стойността на наличността на всеки продукт (цена по наличност), в total сбора ѝ, а в real_total сбора без подаръчната карта, закръглен до 2 знака.
Решение
import pandas as pd
products = pd.read_csv('products.csv')
by_name = products.set_index('name')
stock_value = by_name['price'] * by_name['stock']
total = stock_value.sum()
real_total = round(total - stock_value['Подаръчна карта'], 2)
print(round(total, 2), real_total)stock_value = by_name['price'] * by_name['stock'] е Series с имената в индекса. total е 22 542,30 €, но от тях 19 980 € са подаръчната карта: наличност 999 по 20 €. От първия поглед знаеш, че 999 значи „без ограничение“, а не 999 карти на рафта. real_total = total - stock_value['Подаръчна карта'] дава 2 562,30 €: това е стоката. С имената в индекса изваждаш картата по име, а не по номер 24, който се мести, щом таблицата се подреди по друг начин.
Тест
Провери се
Свързани уроци
Раздел „Свързани уроци“- Нужно отпреди: Първата таблица · Масивът на NumPy · Векторизация · Обобщения и липсващи стойности
- Продължава в: Избиране: [], loc и iloc · Филтри и подреждане · Нови колони · Типове и липсващи стойности
- Задачи по темата: Таблици с pandas