- Нескучный Pandas: выбор строк и столбцов одновременно в .iloc
- Здесь про это:
- Резюме по .loc и .iloc
- Как выбрать строки из Pandas DataFrame по условию
- Синтаксис выборки строк из Pandas DataFrame по условию
- Выберем строки, где цена равна или больше 10
- Выберем строки, в которых цвет зеленый, а форма — прямоугольник
- Выберем строки, где цвет зеленый ИЛИ форма прямоугольная
- Выберем строки, где цена не равна 15
- Опубликовано Вадим В. Костерин
- Аналитикам: большая шпаргалка по Pandas
- Что такое Pandas и зачем он нужен
- Структуры данных: серии и датафреймы
- Создаем датафреймы и загружаем данные
- Исследуем загруженные данные
- Получаем данные из датафреймов
- Указываем нужные строки и колонки
- Если — то. Условные операторы
- Язык запросов
- Считаем производные метрики
- Объединяем несколько датафреймов
- Решаем задачу
Нескучный Pandas: выбор строк и столбцов одновременно в .iloc
Здесь про это:
Рассмотрим несколько примеров, чтобы понять, чем отличается .iloc от .loc.
Выберем две строки и два столбца:
Осуществим выборку строк и столбцов с помощью среза:
Выберем 1 значение из столбца и указанной колонки:
Результат:
Резюме по .loc и .iloc
Доступ к строкам и колонкам по индексу возможен несколькими способами:
- .loc — используется для доступа по строковой метке — т.е. фактически по значению индекса и по названию столбца
- .iloc — используется для доступа по числовому значению (начиная от 0) — т.е. по номеру строки и номеру столбца
Как выбрать строки из Pandas DataFrame по условию
Собираем тестовый набор данных для иллюстрации работы выборки по условию
Color | Shape | Price |
Green | Rectangle | 10 |
Green | Rectangle | 15 |
Green | Square | 5 |
Blue | Rectangle | 5 |
Blue | Square | 10 |
Red | Square | 15 |
Red | Square | 15 |
Red | Rectangle | 5 |
Пишем скрипт:
Синтаксис выборки строк из Pandas DataFrame по условию
Вы можете использовать следующую логику для выбора строк в Pandas DataFrame по условию:
Например, если вы хотите получить строки с зеленым цветом , вам нужно применить:
- Color — это название столбца
- Green — это условие (значение колонки)
А вот полный код Python для нашего примера:
Результат:
Выберем строки, где цена равна или больше 10
Чтобы получить все строки, где цена равна или больше 10, Вам нужно применить следующее условие:
Полный код Python:
Результат:
Выберем строки, в которых цвет зеленый, а форма — прямоугольник
Теперь цель состоит в том, чтобы выбрать строки на основе двух условий:
- Color зеленый; а также
- Shape = прямоугольник
Мы будем использовать символ & для применения нескольких условий. В нашем примере код будет выглядеть так:
Полный код примера Python для выборки Pandas DataFrame:
Результат:
Выберем строки, где цвет зеленый ИЛИ форма прямоугольная
Для достижения этой цели будем использовать символ | следующим образом:
Полный код Python 3:
Выберем строки, где цена не равна 15
Мы будем использовать комбинацию символов !=, чтобы выбрать строки, цена которых не равна 15:
Полный код Pandas DF на питоне:
Результат работы скрипта Python:
Опубликовано Вадим В. Костерин
ст. преп. кафедры ЦЭиИТ. Автор более 130 научных и учебно-методических работ. Лауреат ВДНХ (серебряная медаль). Посмотреть больше записей
Источник
Аналитикам: большая шпаргалка по Pandas
Привет. Я задумывал эту заметку для студентов курса Digital Rockstar, на котором мы учим маркетологов автоматизировать свою работу с помощью программирования, но решил поделиться шпаргалкой по Pandas со всеми. Я ожидаю, что читатель умеет писать код на Python хотя бы на минимальном уровне, знает, что такое списки, словари, циклы и функции.
Что такое Pandas и зачем он нужен
Pandas — это библиотека для работы с данными на Python. Она упрощает жизнь аналитикам: где раньше использовалось 10 строк кода теперь хватит одной.
Например, чтобы прочитать данные из csv, в стандартном Python надо сначала решить, как хранить данные, затем открыть файл, прочитать его построчно, отделить значения друг от друга и очистить данные от специальных символов.
В Pandas всё проще. Во-первых, не нужно думать, как будут храниться данные — они лежат в датафрейме. Во-вторых, достаточно написать одну команду:
Pandas добавляет в Python новые структуры данных — серии и датафреймы. Расскажу, что это такое.
Структуры данных: серии и датафреймы
Серии — одномерные массивы данных. Они очень похожи на списки, но отличаются по поведению — например, операции применяются к списку целиком, а в сериях — поэлементно.
То есть, если список умножить на 2, получите тот же список, повторенный 2 раза.
А если умножить серию, ее длина не изменится, а вот элементы удвоятся.
Обратите внимание на первый столбик вывода. Это индекс, в котором хранятся адреса каждого элемента серии. Каждый элемент потом можно получать, обратившись по нужному адресу.
Еще одно отличие серий от списков — в качестве индексов можно использовать произвольные значения, это делает данные нагляднее. Представим, что мы анализируем помесячные продажи. Используем в качестве индексов названия месяцев, значениями будет выручка:
Теперь можем получать значения каждого месяца:
Так как серии — одномерный массив данных, в них удобно хранить измерения по одному. На практике удобнее группировать данные вместе. Например, если мы анализируем помесячные продажи, полезно видеть не только выручку, но и количество проданных товаров, количество новых клиентов и средний чек. Для этого отлично подходят датафреймы.
Датафреймы — это таблицы. У их есть строки, колонки и ячейки.
Технически, колонки датафреймов — это серии. Поскольку в колонках обычно описывают одни и те же объекты, то все колонки делят один и тот же индекс:
Объясню, как создавать датафреймы и загружать в них данные.
Создаем датафреймы и загружаем данные
Бывает, что мы не знаем, что собой представляют данные, и не можем задать структуру заранее. Тогда удобно создать пустой датафрейм и позже наполнить его данными.
А иногда данные уже есть, но хранятся в переменной из стандартного Python, например, в словаре. Чтобы получить датафрейм, эту переменную передаем в ту же команду:
Случается, что в некоторых записях не хватает данных. Например, посмотрите на список goods_sold — в нём продажи, разбитые по товарным категориям. За первый месяц мы продали машины, компьютеры и программное обеспечение. Во втором машин нет, зато появились велосипеды, а в третьем снова появились машины, но велосипеды исчезли:
Если загрузить данные в датафрейм, Pandas создаст колонки для всех товарных категорий и, где это возможно, заполнит их данными:
Обратите внимание, продажи велосипедов в первом и третьем месяце равны NaN — расшифровывается как Not a Number. Так Pandas помечает отсутствующие значения.
Теперь разберем, как загружать данные из файлов. Чаще всего данные хранятся в экселевских таблицах или csv-, tsv- файлах.
Экселевские таблицы читаются с помощью команды pd.read_excel() . Параметрами нужно передать адрес файла на компьютере и название листа, который нужно прочитать. Команда работает как с xls, так и с xlsx:
Файлы формата csv и tsv — это текстовые файлы, в которых данные отделены друг от друга запятыми или табуляцией:
Оба читаются с помощью команды .read_csv() , символ табуляции передается параметром sep (от англ. separator — разделитель):
При загрузке можно назначить столбец, который будет индексом. Представьте, что мы загружаем таблицу с заказами. У каждого заказа есть свой уникальный номер, Если назначим этот номер индексом, сможем выгружать данные командой df[order_id] . Иначе придется писать фильтр df[df[‘id’] == order_id ] .
О том, как получать данные из датафреймов, я расскажу в одном из следующих разделов. Чтобы назначить колонку индексом, добавим в команду read_csv() параметр index_col , равный названию нужной колонки:
После загрузки данных в датафрейм, хорошо бы их исследовать — особенно, если они вам незнакомы.
Исследуем загруженные данные
Представим, что мы анализируем продажи американского интернет-магазина. У нас есть данные о заказах и клиентах. Загрузим файл с продажами интернет-магазина в переменную orders . Раз загружаем заказы, укажем, что колонка id пойдет в индекс:
Расскажу о четырех атрибутах, которые есть у любого датафрейма: .shape , .columns , .index и .dtypes .
.shape показывает, сколько в датафрейме строк и колонок. Он возвращает пару значений (n_rows, n_columns) . Сначала идут строки, потом колонки.
В датафрейме 5009 строк и 5 колонок.
Окей, масштаб оценили. Теперь посмотрим, какая информация содержится в каждой колонке. С помощью .columns узнаем названия колонок:
Теперь видим, что в таблице есть дата заказа, метод доставки, номер клиента и выручка.
С помощью .dtypes узнаем типы данных, находящихся в каждой колонке и поймем, надо ли их обрабатывать. Бывает, что числа загружаются в виде текста. Если мы попробуем сложить две текстовых значения ‘1’ + ‘1’ , то получим не число 2, а строку ’11’ :
Тип object — это текст, float64 — это дробное число типа 3,14.
C помощью атрибута .index посмотрим, как называются строки:
Ожидаемо, в индексе датафрейма номера заказов: 100762, 100860 и так далее.
В колонке sales хранится стоимость каждого проданного товара. Чтобы узнать разброс значений, среднюю стоимость и медиану, используем метод .describe() :
Наконец, чтобы посмотреть на несколько примеров записей датафрейма, используем команды .head() и .sample() . Первая возвращает 6 записей из начала датафрейма. Вторая — 6 случайных записей:
Получив первое представление о датафреймах, теперь обсудим, как доставать из него данные.
Получаем данные из датафреймов
Данные из датафреймов можно получать по-разному: указав номера колонок и строк, использовав условные операторы или язык запросов. Расскажу подробнее о каждом способе.
Указываем нужные строки и колонки
Продолжаем анализировать продажи интернет-магазина, которые загрузили в предыдущем разделе. Допустим, я хочу вывести столбец sales . Для этого название столбца нужно заключить в квадратные скобки и поставить после них названия датафрейма: orders[‘sales’] :
Обратите внимание, результат команды — новый датафрейм с таким же индексом.
Если нужно вывести несколько столбцов, в квадратные скобки нужно вставить список с их названиями: orders[[‘customer_id’, ‘sales’]] . Будьте внимательны: квадратные скобки стали двойными. Первые — от датафрейма, вторые — от списка:
Перейдем к строкам. Их можно фильтровать по индексу и по порядку. Например, мы хотим вывести только заказы 100363, 100391 и 100706, для этого есть команда .loc[] :
А в другой раз бывает нужно достать просто заказы с 1 по 3 по порядку, вне зависимости от их номеров в таблицемы. Тогда используют команду .iloc[] :
Можно фильтровать датафреймы по колонкам и столбцам одновременно:
Часто вы не знаете заранее номеров заказов, которые вам нужны. Например, если задача — получить заказы, стоимостью более 1000 рублей. Эту задачу удобно решать с помощью условных операторов.
Если — то. Условные операторы
Задача: нужно узнать, откуда приходят самые большие заказы. Начнем с того, что достанем все покупки стоимостью более 1000 долларов:
Помните, в начале статьи я упоминал, что в сериях все операции применяются по-элементно? Так вот, операция orders[‘sales’] > 1000 идет по каждому элементу серии и, если условие выполняется, возвращает True . Если не выполняется — False . Получившуюся серию мы сохраняем в переменную filter_large .
Вторая команда фильтрует строки датафрейма с помощью серии. Если элемент filter_large равен True , заказ отобразится, если False — нет. Результат — датафрейм с заказами, стоимостью более 1000 долларов.
Интересно, сколько дорогих заказов было доставлено первым классом? Добавим в фильтр ещё одно условие:
Логика не изменилась. В переменную filter_large сохранили серию, удовлетворяющую условию orders[‘sales’] > 1000 . В filter_first_class — серию, удовлетворяющую orders[‘ship_mode’] == ‘First’ .
Затем объединили обе серии с помощью логического ‘И’: filter_first_class & filter_first_class . Получили новую серию той же длины, в элементах которой True только у заказов, стоимостью больше 1000, доставленных первым классом. Таких условий может быть сколько угодно.
Язык запросов
Еще один способ решить предыдущую задачу — использовать язык запросов. Все условия пишем одной строкой ‘sales > 1000 & ship_mode == ‘First’ и передаем ее в метод .query() . Запрос получается компактнее.
Отдельный кайф: значения для фильтров можно сохранить в переменной, а в запросе сослаться на нее с помощью символа @: sales > @sales_filter .
Разобравшись, как получать куски данных из датафрейма, перейдем к тому, как считать агрегированные метрики: количество заказов, суммарную выручку, средний чек, конверсию.
Считаем производные метрики
Задача: посчитаем, сколько денег магазин заработал с помощью каждого класса доставки. Начнем с простого — просуммируем выручку со всех заказов. Для этого используем метод .sum() :
Добавим класс доставки. Перед суммированием сгруппируем данные с помощью метода .groupby() :
3.514284e+05 — научный формат вывода чисел. Означает 3.51 * 10 5 . Нам такая точность не нужна, поэтому можем сказать Pandas, чтобы округлял значения до сотых:
Другое дело. Теперь видим сумму выручки по каждому классу доставки. По суммарной выручке неясно, становится лучше или хуже. Добавим разбивку по датам заказа:
Видно, что выручка прыгает ото дня ко дню: иногда 10 долларов, а иногда 378. Интересно, это меняется количество заказов или средний чек? Добавим к выборке количество заказов. Для этого вместо .sum() используем метод .agg() , в который передадим список с названиями нужных функций.
Ого, получается, что это так прыгает средний чек. Интересно, а какой был самый удачный день? Чтобы узнать, отсортируем получившийся датафрейм: выведем 10 самых денежных дней по выручке:
Команда разрослась, и её теперь неудобно читать. Чтобы упростить, можно разбить её на несколько строк. В конце каждой строки ставим обратный слеш \ :
В самый удачный день — 18 марта 2014 года — магазин заработал 27 тысяч долларов с помощью стандартного класса доставки. Интересно, откуда были клиенты, сделавшие эти заказы? Чтобы узнать, надо объединить данные о заказах с данными о клиентах.
Объединяем несколько датафреймов
До сих пор мы смотрели только на таблицу с заказами. Но ведь у нас есть еще данные о клиентах интернет-магазина. Загрузим их в переменную customers и посмотрим, что они собой представляют:
Мы знаем тип клиента, место его проживания, его имя и имя контактного лица. У каждого клиента есть уникальный номер id . Этот же номер лежит в колонке customer_id таблицы orders . Значит мы можем найти, какие заказы сделал каждый клиент. Например, посмотрим, заказы пользователя CG-12520 :
Вернемся к задаче из предыдущего раздела: узнать, что за клиенты, которые сделали 18 марта заказы со стандартной доставкой. Для этого объединим таблицы с клиентами и заказами. Датафреймы объединяют с помощью методов .concat() , .merge() и .join() . Все они делают одно и то же, но отличаются синтаксисом — на практике достаточно уметь пользоваться одним из них.
Покажу на примере .merge() :
В .merge() я сначала указал названия датафреймов, которые хочу объединить. Затем уточнил, как именно их объединить и какие колонки использовать в качестве ключа.
Ключ — это колонка, связывающая оба датафрейма. В нашем случае — номер клиента. В таблице с заказами он в колонке customer_id , а таблице с клиентами — в индексе. Поэтому в команде мы пишем: left_on=’customer_id’, right_index=True .
Решаем задачу
Закрепим полученный материал, решив задачу. Найдем 5 городов, принесших самую большую выручку в 2016 году.
Для начала отфильтруем заказы из 2016 года:
Город — это атрибут пользователей, а не заказов. Добавим информацию о пользователях:
Cруппируем получившийся датафрейм по городам и посчитаем выручку:
Отсортируем по убыванию продаж и оставим топ-5:
Возьмите данные о заказах и покупателях и посчитайте:
- Сколько заказов, отправлено первым классом за последние 5 лет?
- Сколько в базе клиентов из Калифорнии?
- Сколько заказов они сделали?
- Постройте сводную таблицу средних чеков по всем штатам за каждый год.
Через некоторое время выложу ответы в Телеграме. Подписывайтесь, чтобы не пропустить ответы и новые статьи.
Кстати, большое спасибо Александру Марфицину за то, что помог отредактировать статью.
Источник