Получив новую таблицу, не спешите считать. Сначала стоит понять, что в ней лежит: какие столбцы, какого типа, нет ли пропусков, какие значения встречаются. На это уходит пара минут и пять методов.
info: столбцы, типы, пропуски
import pandas as pd
orders = pd.read_csv("data/shop_orders.csv")
orders.info()<class 'pandas.DataFrame'> RangeIndex: 2448 entries, 0 to 2447 Data columns (total 9 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 order_id 2448 non-null int64 1 date 2448 non-null str 2 customer_id 2448 non-null str 3 city 2448 non-null str 4 channel 2448 non-null str 5 category 2448 non-null str 6 product 2448 non-null str 7 price 2448 non-null int64 8 quantity 2448 non-null int64 dtypes: int64(3), str(6) memory usage: 114.8 KB
Читаем сверху вниз: 2448 строк с индексом от 0 до 2447, 9 столбцов. Для каждого столбца — сколько в нём
непустых значений (Non-Null Count) и тип (Dtype). Здесь у всех столбцов 2448 непустых значений из 2448 —
пропусков нет. Если бы в столбце было меньше, значит, часть значений пропущена: с этим мы встретимся в модуле
об очистке данных.
Обратите внимание на date: тип str, то есть даты прочитаны как обычный текст. Пока нам это не мешает;
превращать их в настоящие даты научимся позже.
Последняя строка — сколько памяти занимает таблица. На вашем компьютере это число будет другим: оно зависит от того, как pandas хранит текст на конкретной машине.
describe: сводка по числам
orders.describe()| order_id | price | quantity | |
|---|---|---|---|
| count | 2448.000000 | 2448.000000 | 2448.000000 |
| mean | 10787.296977 | 688.721405 | 2.128268 |
| std | 456.972637 | 537.676249 | 1.386154 |
| min | 10001.000000 | 150.000000 | 1.000000 |
| 25% | 10390.000000 | 320.000000 | 1.000000 |
| 50% | 10789.000000 | 540.000000 | 2.000000 |
| 75% | 11182.000000 | 790.000000 | 3.000000 |
| max | 11576.000000 | 3200.000000 | 10.000000 |
describe берёт только числовые столбцы и считает по каждому восемь показателей:
count— сколько значений;mean— среднее;std— стандартное отклонение: насколько значения в среднем далеки от среднего (подробно — в модуле о статистике);minиmax— наименьшее и наибольшее;25%,50%,75%— значения, ниже которых лежит четверть, половина и три четверти данных.50%называют медианой: половина значений меньше неё, половина — больше.
Сводка по order_id бессмысленна: номер заказа — это число, но не величина, среднее у него считать незачем.
pandas этого знать не может — решать, что имеет смысл, приходится нам.
У столбца price среднее 689, а медиана 540: половина строк дешевле 540 ₽, но несколько дорогих товаров тянут
среднее вверх.
describe есть и у отдельного столбца — тогда результат не таблица, а Series с метками count, mean…:
orders["price"].describe()count 2448.000000 mean 688.721405 std 537.676249 min 150.000000 25% 320.000000 50% 540.000000 75% 790.000000 max 3200.000000 Name: price, dtype: float64
Сохраните в quantity_stats сводку describe по столбцу quantity, а в typical — медиану количества,
достав её из сводки по метке.
"50%" — в кавычках и со знаком процента.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
quantity_stats = ...
typical = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
quantity_stats = orders["quantity"].describe()
typical = quantity_stats["50%"]value_counts: как часто встречается каждое значение
У текстовых столбцов средних нет. Главный вопрос к ним — какие значения есть и сколько раз каждое встречается.
На него отвечает value_counts:
orders["city"].value_counts()city Москва 948 Санкт-Петербург 589 Казань 341 Екатеринбург 312 Новосибирск 258 Name: count, dtype: int64
Результат — Series, в котором метки индекса — сами значения столбца, а значения — сколько раз они встретились. Строки отсортированы от самого частого к самому редкому. Раз это Series с метками, число можно достать по метке:
city_counts = orders["city"].value_counts()
print(city_counts["Казань"])
print(city_counts.index)341 Index(['Москва', 'Санкт-Петербург', 'Казань', 'Екатеринбург', 'Новосибирск'], dtype='str', name='city')
Индекс можно читать как список: city_counts.index[0] — первая метка, то есть самый частый город.
Не забывайте, что считаются строки, то есть позиции заказов: 948 — это не число заказов из Москвы, а число купленных там позиций.
Сохраните в channel_counts, сколько строк приходится на каждый канал продаж (столбец channel), а в app_rows —
число строк, купленных через приложение: достаньте его из channel_counts по метке "приложение".
orders["channel"].value_counts().channel_counts["приложение"].Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
channel_counts = ...
app_rows = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
channel_counts = orders["channel"].value_counts()
app_rows = channel_counts["приложение"]nunique и unique: сколько разных значений и какие
nunique (number of unique) считает, сколько в столбце разных значений:
print(orders["city"].nunique())
print(orders["product"].nunique())5 20
У таблицы nunique возвращает это число для каждого столбца сразу:
orders.nunique()order_id 1576 date 358 customer_id 213 city 5 channel 3 category 5 product 20 price 20 quantity 10 dtype: int64
Так и находится ответ на вопрос из первого урока: строк 2448, а разных order_id — 1576. Заказов 1576.
Сами разные значения возвращает unique — в том порядке, в каком они впервые встретились в столбце:
orders["channel"].unique()<StringArray> ['маркетплейс', 'приложение', 'сайт'] Length: 3, dtype: str
unique возвращает не список, а массив — так pandas хранит значения столбца. Слово перед списком значений
(StringArray или ArrowStringArray) зависит от компьютера и на результат не влияет. Когда нужен обычный
список Python, массив передают в list(...); отсортированный список вернёт sorted(...):
list(orders["channel"].unique())['маркетплейс', 'приложение', 'сайт']
Что выведет print(orders["order_id"].nunique() == len(orders))?
len(orders) — число строк, 2448. nunique() — число разных номеров заказов, 1576: в одном заказе бывает несколько строк. Числа не равны.Сохраните в n_days, в скольких разных днях года были продажи (столбец date), а в categories — список
категорий товаров (столбец category), отсортированный по алфавиту.
nunique().sorted(orders["category"].unique()) — отсортированный список.Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
n_days = ...
categories = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
n_days = orders["date"].nunique()
categories = sorted(orders["category"].unique())Сохраните в product_counts, сколько строк приходится на каждый товар (столбец product). Затем в best_seller —
название товара, который встречается чаще всех, а в best_rows — в скольких строках он встречается.
value_counts сортирует от частого к редкому: самый частый товар — первая метка индекса.product_counts.index[0] — первая метка. Число строк — product_counts.max().Заготовка упражнения обновилась с тех пор, как вы сохранили свой код.
Вернуть заготовку? Ваш код в этом упражнении будет удалён.
product_counts = ...
best_seller = ...
best_rows = ...Упражнение пока не решено, поэтому для ячеек ниже выполнено эталонное решение — ваш код не изменён.
product_counts = orders["product"].value_counts()
best_seller = product_counts.index[0]
best_rows = product_counts.max()Итоги
info()— столбцы, типы и число непустых значений;describe()— сводка по числовым столбцам.value_counts()— сколько раз встречается каждое значение: Series, где метки — значения столбца.nunique()— сколько разных значений;unique()— какие именно.- Прежде чем считать, спросите себя, что значит одна строка таблицы: здесь это позиция заказа, а не заказ.