Что такое series в pandas
Изучаем pandas. Урок 2. Структуры данных Series и DataFrame
Во втором уроке мы познакомимся со структурами данных pandas – это Series и DataFrame. Основное внимание будет уделено вопросам создания и получения доступа к элементам данных структур, а также общим понятиям, которые позволят более интуитивно работать с ними в будущем.
Введение
Структура данных Series
Пора переходить к практике!
Импортируем нужные нам библиотеки.
Создать структуру Series можно на базе различных типов данных:
Конструктор класса Series выглядит следующим образом:
data – массив, словарь или скалярное значение, на базе которого будет построен Series;
copy – создает копию массива данных, если параметр равен True в ином случае ничего не делает.
В большинстве случаев, при создании Series, используют только первые два параметра. Рассмотрим различные варианты как это можно сделать.
Создание Series из списка Python
Самый простой способ создать Series – это передать в качестве единственного параметра в конструктор класса список Python.
Обратите внимание на левый столбец, в нем содержатся метки, которые мы передали в качестве index параметра при создании структуры. Правый столбец – это по-прежнему элементы нашей структуры.
Создание Series из ndarray массива из numpy
Создадим простой массив из пяти чисел, аналогичный списку из предыдущего раздела. Библиотеки pandas и numpy должны быть предварительно импортированы.
Теперь создадим Series с буквенными метками.
Создание Series из словаря (dict)
Еще один способ создать структуру Series – это использовать словарь для одновременного задания меток и значений.
Создание Series с использованием константы
Рассмотрим еще один способ создания структуры. На этот раз значения в ячейках структуры будут одинаковыми.
В созданной структуре Series имеется три элемента с одинаковым содержанием.
Работа с элементами Series
Можно использовать метку, тогда работа с Series будет похожа на работу со словарем (dict) в Python.
Доступно получение slice’ов.
В поле для индекса можно поместить условное выражение.
Со структурами Series можно работать как с векторами: складывать, умножать вектор на число и т.п.
Структура данных DataFrame
Если Series представляет собой одномерную структуру, которую для себя можно представить как таблицу с одной строкой, то DataFrame – это уже двумерная структура – полноценная таблица с множеством строк и столбцов.
Конструктор класса DataFrame выглядит так:
index – список меток для записей (имена строк таблицы);
columns – список меток для полей (имена столбцов таблицы);
copy – создает копию массива данных, если параметр равен True в ином случае ничего не делает.
Структуру DataFrame можно создать на базе:
Создание DataFrame из словаря
В данном случае будет использоваться одномерный словарь, элементами которого будут списки, структуры Series и т.д.
Создание DataFrame из списка словарей
Создание DataFrame из двумерного массива
Работа с элементами DataFrame
Основные подходы представлены в таблице ниже.
Операция | Синтаксис | Возвращаемый результат |
Выбор столбца | df[col] | Series |
Выбор строки по метке | df.loc[label] | Series |
Выбор строки по индексу | df.iloc[loc] | Series |
Слайс по строкам | df[0:4] | DataFrame |
Выбор строк, отвечающих условию | df[bool_vec] | DataFrame |
Теперь посмотрим, как использовать данные операций на практике.
Операция: выбор столбца.
Операция: выбор строки по метке.
Операция: выбор строки по индексу.
Операция: slice по строкам.
Операция: выбор строк, отвечающих условию.
P.S.
Изучаем pandas. Урок 2. Структуры данных Series и DataFrame : 6 комментариев
Опечатка: случае[т]
В большинстве случает, при создании Series
P.S. Спасибо за статью!
> Конструктор класса Series выглядит следующим образом:
> … fastpath=False
Про этот параметр ничего не сказали.
И слово “slice”, которое вы как только не склоняете здесь и далее в книге, переводится как “срез”. Это вполне себе русское и подходящее по смыслу слово.
Как мне кажется, ‘slice’ стало уже сленговым словом, и его вполне можно употреблять. Но слово ‘срез’ звучит тоже не плохо))) В данном случае выбор был сделан в пользу первого.
Pandas: структуры данных Series и DataFrame
В статье мы расскажем об удобном фреймворке pandas для автоматизации работы с большими данными: одномерными и многомерными массивами, а также для анализа статистических данных.
Что такое Pandas?
Обычно Pandas используется совсместно с другими библиотками Python. Кроме того, в Pandas уже встроена библиотека NumPy, структура этих двух библиотек несколько похожа. Pandas также используется с SciPy для проведения статистического анализа или с Matplotlib для построения графиков и визуализации данных.
Если для того, чтобы прочитать файл с таблицей в стандартном Python необходимо придумать, в каком виде хранить данные, открыть файл, затем построчно прочитать его, как-то разделить значения, например, по специальным символам: новой строке, знакам препинания и т.д., а также удалить лишние символы, то для того, чтобы открыть файл с массивом данных в pandas нужно написать всего одну команду.
Шаг 1. Установка Pandas
Установить Pandas можно с помощью встроенного в Python инструмента pip, запустив следующую команду:
Открыть файл с помощью Pandas
Так как Pandas не является стандартной библиотекой Python, ее нужно импортировать. Давайте импортируем ее и дадим ей сокращенное название “pd”, чтобы быстрее обращаться к ней.
Чтение csv файла с помощью pandas:
У функции read_csv есть еще несколько параметров, например:
Со всеми параметрами можно ознакомиться в официальной документации.
Чтение excel с помощью pandas:
Также как и read_csv имеет несколько параметров, например, название или номер листа, который нужно прочитать.
Pandas предоставляет работать не только с excel файлами, но и с:
Основные типы данных в Pandas
Тип данных сообщает информацию о том, как Python может манипулировать данными. При анализе данных информация о типе данных позволяет одним образом обрабатывать данные одного типа и избежать ошибок.
Структуры данных в Pandas: отличия Series и DataFrame
Для того, чтобы сразу увидеть разницу между двумя основными структурами данных в Pandas можно проассоциировать DataFrame с таблицей со строками и колонками. Каждое значение внутри DataFrame имеет 2 индекса: ряда и колонки.
Структуры данных в Pandas: Series
В стандартном списке мы можем обращаться к элементу по его индексу или порядковому номеру, в Series тоже так можно, но кроме того, в Series индексами послужить данные любого типа: даты, текст, числа, id и др.
Создание Series
Для работы с Pandas рекомендуем предварительно установить jupyter notebook.
Можно скачать и установить пакет Anaconda с официального сайта.
После установки в директории Anaconda будет графический редактор jupyter notebook. Запускаем его и создаем новый ноутбук.
Статья на хабре об особенностях Jupyter Notebook.
Итак, давайте попробуем создать Series, содержащий названия дней недели и присвоим им текстовые индексы с порядковым номером:
P.S. В jupyter notebook можно обойтись и без функции display
Если не указывать индекс явно, он создается автоматически в виде порядковых номеров элементов, начиная с 0:
Обращение к элементам Series
Давайте попробуем обратиться к элементу Series по индексу.
Есть несколько способов это сделать.
Разберем пример: у нас есть данные типа Series с днями недели и их индексами:
Если нам необходимо “достать” определенное значение из Series, например, второй день недели или “вторник”, то мы можем сделать это:
Изменение элементов Series
Мы уже упоминали, что серии напоминают списки в python. Давайте сравним работу с ними. Попробуем умножить на 2 список и Series.
Кстати, если нужны только значения, то можно использовать метод “.values”:
Структуры данных в Pandas: DataFrame
Обычно в работе с данными имеют дело не с единичными значениями, а с целыми группами данных, например, в продажах обычно учитывают множество факторов: цену, количество продаж, количество товаров, наличие скидок, средний чек и так далее.
Для хранения такой информации хорошо подходят датафреймы (DataFrame).
Создаем DataFrame
Обычно в одной колонке таблицы хранятся данные, описывающие одну и ту же характеристику. Давайте рассмотрим простой пример, где мы хотим посмотреть на динамику продаж:
Создать датафрейм можно двумя способами:
Получение информации о датафрейме
Метод .info() позволяет увидеть информацию о датафрейме: названии колонок, количестве элементов, пропусков и типе данных, хранящихся в колонах.
Пустые ячейки в DataFrame Pandas
Иногда в таблицах бывают пропуски. Рассмотрим пример с продажами за 3 месяца: январь, февраль и март. В январе было продано 8 яблок, 9 бананов и 7 апельсинов, а в феврале бананы не продавались совсем, зато было продано 7 лимонов:
То, что в некоторые месяцы не продавалась определенная группа товаров, не нарушило структуру таблицы: пропуски заполняются значением “NaN”.
В последствии, эти пропуски можно заполнить определенными значениями, удались или сгруппировать.
Подробнее о том как работать с пропусками можно почитать здесь.
Итак, мы рассмотрели особые структуры данных в Pandas: Series и DataFrame. В следующей статье рассмотрим, как решать практические задачи в области анализа данных.
Pandas
Pandas — это библиотека Python для обработки и анализа структурированных данных, её название происходит от «panel data» («панельные данные»). Панельными данными называют информацию, полученную в результате исследований и структурированную в виде таблиц. Для работы с такими массивами данных и создан Pandas.
Работа с открытым кодом
Pandas — это opensource-библиотека, то есть ее исходный код в открытом доступе размещен на GitHub. Пользователи могут добавлять туда свой код: вносить пояснения, дополнять методы работы и обновлять разделы. Для работы потребуется компилятор (программа, которая переводит текст с языка программирования в машинный код) C/C++ и среда разработки Python. Подробный процесс установки компилятора С для разных операционных систем можно найти в документации Pandas.
В каких профессиях понадобится библиотека?
Навык работы с этой библиотекой пригодится дата-сайентистам или аналитикам данных. С помощью Pandas эти специалисты могут группировать и визуализировать данные, создавать сводные таблицы и делать выборку по определенным признакам.
Как установить Pandas
Шаг 1. На официальном сайте Pandas указан самый простой способ начать работу с библиотекой. Для этого потребуется установить Anaconda — дистрибутив (форма распространения программного обеспечения, набор библиотек или программного кода для установки программы) для Python с набором библиотек. Безопасно скачать его можно на официальном сайте.
Вот несколько советов по установке Anaconda для новичков:
Шаг 2. В командной строке Anaconda запустите JupyterLab — это интерактивная среда для работы с кодом, данными и блокнотами, которая входит в пакет дистрибутива.
Шаг 3. Создайте в JupyterLab новый блокнот Python3.
Шаг 4. В первой ячейке пропишите: import pandas as pd, после этого в следующих ячейках можно писать код.
DataFrame и Series
Чтобы анализировать данные с помощью Pandas, нужно понять, как устроены структуры этих данных внутри библиотеки. В первую очередь разберем, что такое DataFrame и Series.
Pandas Series (серия) — это одномерный массив. Визуально он похож на пронумерованный список: слева в колонке находятся индексы элементов, а справа — сами элементы.
Индексом может быть числовой показатель (0, 1, 2…), буквенные значения (a, b, c…) или другие данные, выбранные программистом. Если особое значение не задано, то числовые индексы проставляются автоматически. Например, от 0 до 5 как в примере выше.
Такая нумерация называется RangeIndex, в ней всегда содержатся числа от 0 до определенного числа N, которое обозначает количество элементов в серии. Собственные значения индексов задаются в квадратных скобках через index, как в примере ниже:
Индексы помогают обращаться к элементам серии и менять их значения. Например, чтобы в нашей серии [5, 6, 7, 8, 9, 10] заменить значения некоторых элементов на 0, мы прописываем индексы нужных элементов и указываем, что они равны нулю:
Можно сделать выборку по нескольким индексам, чтобы ненужные элементы в серии не отображались:
Pandas DataFrame — это двумерный массив, похожий на таблицу/лист Excel (кстати, данные из Excel можно читать с помощью команды pandas.read_excel(‘file.xls’)). В нем можно проводить такие же манипуляции с данными: объединять в группы, сортировать по определенному признаку, производить вычисления. Как любая таблица, датафрейм состоит из столбцов и строк, причем столбцами будут уже известные объекты — Series.
Чтобы проверить, действительно ли серии — это части датафрейма, можно извлечь любую колонку из таблицы. Возьмем набор данных о нескольких странах СНГ, их площади и населении и выберем колонку country:
… ‘country’: [‘Kazakhstan’, ‘Russia’, ‘Belarus’, ‘Ukraine’],
… ‘population’: [17.04, 143.5, 9.5, 45.5],
… ‘square’: [2724902, 17125191, 207600, 603628]
country population square
0 Kazakhstan 17.04 2724902
1 Russia 143.50 17125191
2 Belarus 9.50 207600
3 Ukraine 45.50 603628
В итоге получится простая серия, в которой сохранятся те же индексы по строкам, что и в исходном датафрейме.
Name: country, dtype: object
Аналитика данных с нуля
Получите востребованные навыки и освойте профессию аналитика данных за 6 месяцев. Дополнительная скидка 5% по промокоду BLOG.
Кроме этого, у датафрейма есть индексы по столбцам, которые задаются вручную. Для простоты написания кода обозначим страны индексами из двух символов: Kazakhstan — KZ, Russia — RU и так далее:
… ‘country’: [‘Kazakhstan’, ‘Russia’, ‘Belarus’, ‘Ukraine’],
… ‘population’: [17.04, 143.5, 9.5, 45.5],
… ‘square’: [2724902, 17125191, 207600, 603628]
country population square
KZ Kazakhstan 17.04 2724902
RU Russia 143.50 17125191
BY Belarus 9.50 207600
UA Ukraine 45.50 603628
>>> df.index = [‘KZ’, ‘RU’, ‘BY’, ‘UA’]
>>> df.index.name = ‘Country Code’
country population square
KZ Kazakhstan 17.04 2724902
RU Russia 143.50 17125191
BY Belarus 9.50 207600
UA Ukraine 45.50 603628
>>> df.loc[[‘KZ’, ‘RU’], ‘population’]
Name: population, dtype: float64
Также в DataFrame производят математические вычисления. Например, рассчитаем плотность населения каждой страны в нашем датафрейме. Данные в колонке population (численность населения) делим на square (площадь) и получаем новые данные в колонке density, которые показывают плотность населения:
>>> df[‘density’] = df[‘population’] / df[‘square’] * 1000000
country population square density
KZ Kazakhstan 17.04 2724902 6.253436
RU Russia 143.50 17125191 8.379469
BY Belarus 9.50 207600 45.761079
UA Ukraine 45.50 603628 75.377550
Data Science с нуля
Закрепите навыки Data Science и получите перспективную профессию за 13 месяцев. Дополнительная скидка 5% по промокоду BLOG.
Чтение и запись данных
Доступ по индексу в DataFrame
>>> df = pd.DataFrame([[1, 2], [4, 5], [7, 8]],
Name: viper, dtype: int64
2 1000 2000 3000 4000
Name: 0, dtype: int64
Группировка и агрегирование данных
Обратите внимание на as_index=False, эта часть кода отвечает за то, чтобы сохранить числовые индексы в результатах группировки и вычисления.
Сводные таблицы в Pandas
Для примера возьмем условный набор данных с простыми категориями one / two, small / large и числовыми значениями. В столбце A две категории foo / bar складываются в слово foobar — текст, который используется в программировании для условного обозначения. В этом случае он указывает, что мы делим данные на две группы по неопределенному признаку.
0 foo one small 1 2
1 foo one large 2 4
2 foo one large 2 5
3 foo two small 3 5
4 foo two small 3 6
5 bar one large 4 6
6 bar one small 5 8
7 bar two small 6 9
8 bar two large 7 9
>>> table = pd.pivot_table(df, values=’D’, index=[‘A’, ‘B’],
Мы разбиваем данные на две категории: bar и foo, в каждой из них будут подгруппы со значениями one и two, которые в свою очередь делятся на small и large. В сводной таблице мы вычисляем, сколько объектов будет в каждой группе. Для этого используем методы values, index, columns и aggfunc:
Аналитика данных с нуля
Получите востребованные навыки и освойте профессию аналитика данных за 6 месяцев. Дополнительная скидка 5% по промокоду BLOG.
Визуализация данных в Pandas
Дата-аналитики составляют наглядные графики с помощью Pandas и библиотеки Matplotlib. В этой связке Pandas отвечает за вычислительную часть работы, а вспомогательная библиотека «создает» картинку.
Посмотрим на данные о продажах в одной из компаний:
В таблице видно, что одни пользователи совершили уже более 7 000 покупок, а некоторые — сделали первую. Чтобы увидеть подробную картину, составляем график sns.distplot. На горизонтальной оси будет отображаться число покупок на одного покупателя, а на вертикальной — количество покупателей, которые совершили именно столько покупок в этой компании. Так по графику можно определить, что самой многочисленной оказалась группа клиентов, которая совершила всего несколько покупок, а группа постоянных клиентов немногочисленная.
distplot — это график, который визуализирует гистограммы, то есть распределяет данные по столбцам. Каждому столбцу соответствует доля количества объектов в данной группе. Также distplot показывает плотность распределения — плавный линейный график, в котором самая высокая точка указывает на наибольшее количество объектов.
Кроме этого, в Pandas есть другие виды графиков:
Например, можно отследить взаимосвязь между тем, сколько минут посетитель проводит в торговом центре и сколько магазинов успевает посетить за это время: кто-то за 30 минут успеет зайти в 5 бутиков, а кто-то обойдет 16. При этом каждый посетитель на графике будет отображаться отдельной точкой.
Data Science с нуля
Закрепите навыки Data Science и получите перспективную профессию за 13 месяцев. Дополнительная скидка 5% по промокоду BLOG.
Структуры данных
Основными рабочими структурами данных в Pandas являются объекты Series и DataFrame, но прежде чем переходить к их изучению, давайте сделаем необходимые импорты:
Series
Давайте создадим серию из массива NumPy:
Если индекс не указан, как здесь:
то он будет создан автоматически, а его значения будут совпадать с значениями индексов массива data
Важно отметить, что элементы индекса могут иметь одинаковые значения:
Серии также могут быть созданы из словарей:
Если вместе со словарем указан еще и индекс, то из данных будут извлечены только те элементы, ключи которых присутствуют в index :
В качестве data может выступать скалярное значение, которое будет сопоставлено каждому индексу:
Серии являются массиво-подобными объектами, поэтому они могут быть переданы в качестве аргументов, практически во все функции NumPy и в этом ракурсе ведут себя практически точно так же как и array объекты:
Например, вот обычное извлечение разреженного среза (среза с заданным шагом):
Результат булевой индексации (применения логической маски):
Извлечение элементов с помощью массива индексов:
Применение функции NumPy к серии и выполнение векторизованной арифметической операции:
При этом серии подобны словарю в том смысле, что доступ к элементам может быть выполнен по идентификаторам (меткам) в index :
Как и в NumPy, все операции над сериями векторизованы, но все они выполняются с выравниванием индекса:
Выравнивание означает, что операции выполняются только над элементами с одинаковым индексом, остальные индексы попадают в результат со значениями NaN.
Зачастую, данные в сериях являются значениями некоторой переменной из конкретной прикладной области, поэтому полезно давать сериям осмысленные названия:
Сменить название можно с помощью метода rename() :
DataFrame
first_column | second_column | third_column | |
---|---|---|---|
a | 4.0 | NaN | 2.0 |
b | 3.0 | NaN | NaN |
c | 2.0 | 9.0 | 3.0 |
d | 1.0 | 8.0 | 4.0 |
e | 0.0 | 7.0 | NaN |
f | NaN | 6.0 | 5.0 |
g | NaN | 5.0 | 6.0 |
Можно указать необходимые индексы и столбцы:
second_column | third_column | fourth_column | |
---|---|---|---|
c | 5.0 | 3.0 | NaN |
d | 6.0 | 4.0 | NaN |
f | 8.0 | 5.0 | NaN |
g | 9.0 | 6.0 | NaN |
z | NaN | NaN | NaN |
Датафрейм может быть создан из структурированного массива NumPy:
col_1 | col_2 | col_3 | |
---|---|---|---|
0 | a | 11 | 0.899902 |
1 | b | 22 | 0.799805 |
2 | c | 33 | 0.700195 |
col_1 | col_2 | col_3 | |
---|---|---|---|
one | a | 11 | 0.899902 |
two | b | 22 | 0.799805 |
three | c | 33 | 0.700195 |
Датафрейм может быть создан из списка словарей:
Датафрейм может быть создан из словаря словарей:
Датафрейм может быть создан из словаря словарей с ключами-кортежами, в результате чего может быть получена иерархическая индексация как строк так и столбцов::
group_1 | group_2 | ||||||
---|---|---|---|---|---|---|---|
x | y | z | x | y | z | ||
i | m | 11 | 33 | 55 | 11 | 33 | 55 |
n | 22 | 44 | 66 | 22 | 44 | 66 | |
j | m | 11 | 33 | 55 | 11 | 33 | 55 |
n | 22 | 44 | 66 | 22 | 44 | 66 |
Датафрейм можно воспринимать как словарь в котором значениями являются серии, а ключами их названия, поэтому выбор некоторого столбца в таблице, добавление нового или удаление некоторого из них может осуществляться тем же синтаксисом, что и при работе с словарями:
Например, добавить новый столбец в датафрейм можно точно так же как и новый элемент в словарь, т.е. просто указать ключ и присвоить ему новую серию:
col_1 | col_2 | col_3 | |
---|---|---|---|
0 | 9 | 3 | 900 |
1 | 9 | 5 | 900 |
2 | 5 | 1 | 500 |
3 | 6 | 5 | 600 |
4 | 3 | 8 | 300 |
Наверное вы обратили внимание на то, что новыми столбцами датафрейма могут быть результаты вычислений над имеющимися столбцами. В примере выше мы взяли столбец col_1, умножили его на 100, а результат присвоили новому столбцу, который стал частью исходного датафрейма. Это очень удобно и мы можем этим успешно и часто пользоваться. А в самих вычислениях может учавствовать несколько столбцов, например, мы можем выполнить сравнение значений нескольких столбцов, а результат добавить в тот же самый датафрейм:
col_1 | col_2 | col_3 | col_4 | |
---|---|---|---|---|
0 | 9 | 3 | 900 | True |
1 | 9 | 5 | 900 | True |
2 | 5 | 1 | 500 | True |
3 | 6 | 5 | 600 | True |
4 | 3 | 8 | 300 | False |
Удалить столбец можно с помощью, уже знакомого по словарям, метода pop() :
Данный метод удаляет указанный элемент, но как вы обратили внимание, возвращает его значение в виде серии. Тем не менее, столбец действительно удалился:
col_2 | col_3 | col_4 | |
---|---|---|---|
0 | 3 | 900 | True |
1 | 5 | 900 | True |
2 | 1 | 500 | True |
3 | 5 | 600 | True |
4 | 8 | 300 | False |
Вставить столбец в нужное место можно с помощью метода insert :
col_1 | col_2 | col_3 | col_4 | |
---|---|---|---|---|
0 | 0.003333 | 3 | 900 | True |
1 | 0.005556 | 5 | 900 | True |
2 | 0.002000 | 1 | 500 | True |
3 | 0.008333 | 5 | 600 | True |
4 | 0.026667 | 8 | 300 | False |
Если новому столбцу присваивается скалярное значение, то им будет заполнен весь столбец:
col_1 | col_2 | col_3 | col_4 | col_5 | |
---|---|---|---|---|---|
0 | 0.003333 | 3 | 900 | True | 10 |
1 | 0.005556 | 5 | 900 | True | 10 |
2 | 0.002000 | 1 | 500 | True | 10 |
3 | 0.008333 | 5 | 600 | True | 10 |
4 | 0.026667 | 8 | 300 | False | 10 |
Если вставить серию у которой значения индекса не совпадают с индексами датафрейма, то произойдет выравнивание индексов:
col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | |
---|---|---|---|---|---|---|
0 | 0.003333 | 3 | 900 | True | 10 | 10.0 |
1 | 0.005556 | 5 | 900 | True | 10 | NaN |
2 | 0.002000 | 1 | 500 | True | 10 | 10.0 |
3 | 0.008333 | 5 | 600 | True | 10 | NaN |
4 | 0.026667 | 8 | 300 | False | 10 | 10.0 |
Метод assign() позволяет создавать столбцы, которые могут быть получены в результате вычислений:
При этом возвращается новый датафрейм, а исходный остается без изменений:
Метод assign() так же позволяет использовать лямбда-функции:
a | b | c | d | |
---|---|---|---|---|
0 | 8 | 4 | 6 | 38 |
1 | 3 | 1 | 4 | 7 |
2 | 7 | 9 | 0 | 63 |
3 | 0 | 4 | 2 | 2 |
4 | 2 | 4 | 5 | 13 |
Индексация строк датафреймов
Допустим у нас есть следующий датафрейм:
Что бы обратиться к его строкам по их индексу (меткам) в index перед оператором [] нужно указать индексатор loc :
А что бы обратиться к той же строке, но по целочисленному индексу, нужен индексатор iloc :
Возвращаемые индексаторами, объекты являются сериями:
Причем индексы этих серий, совпадают с названиями столбцов датафрейма, что в общем-то более чем логично:
Что бы получить доступ к элементу извлеченной строки, нужно принять во внимание, что этот элемент находится на пересечении строки и столбца, поскольку строка уже извлечена, то остается указать просто название нужного столбца в качестве индекса во втором операторе [] :
Индексаторами loc и iloc можно воспользоваться для выделения срезов (фрагментов таблиц):
Добиться аналогичного результата можно, просто, указав начальный и конечный индекс среза:
Так же как и в NumPy получить датафрейм из нужных строк можно с помощью логических массивов:
Выравнивание данных
При выполнении арифметических операций с участием датафреймов происходит выравнивание данных, как по строкам, так и по столбцам, а результатом операции будет датафрейм с объединением меток строк и столбцов. Для примера сделаем два датафрейма:
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
row_0 | 0 | 1 | 2 | 3 |
row_1 | 4 | 5 | 6 | 7 |
row_2 | 8 | 9 | 10 | 11 |
row_3 | 12 | 13 | 14 | 15 |
row_4 | 16 | 17 | 18 | 19 |
row_5 | 20 | 21 | 22 | 23 |
row_6 | 24 | 25 | 26 | 27 |
col_0 | col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | |
---|---|---|---|---|---|---|---|
row_0 | 0 | 1 | 2 | 3 | 4 | 5 | 6 |
row_1 | 7 | 8 | 9 | 10 | 11 | 12 | 13 |
row_2 | 14 | 15 | 16 | 17 | 18 | 19 | 20 |
row_3 | 21 | 22 | 23 | 24 | 25 | 26 | 27 |
А теперь выполним их произведение:
col_0 | col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | |
---|---|---|---|---|---|---|---|
row_0 | 0.0 | 1.0 | 4.0 | 9.0 | NaN | NaN | NaN |
row_1 | 28.0 | 40.0 | 54.0 | 70.0 | NaN | NaN | NaN |
row_2 | 112.0 | 135.0 | 160.0 | 187.0 | NaN | NaN | NaN |
row_3 | 252.0 | 286.0 | 322.0 | 360.0 | NaN | NaN | NaN |
row_4 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
row_5 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
row_6 | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Если выполняется операция между датафреймом и серией, то индексы серии выравниваются по столбцам датафрейма, а затем происходит транслирование серии по всему датафрейму, например
col_0 | col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | |
---|---|---|---|---|---|---|---|
row_0 | 0 | 1 | 4 | 9 | 16 | 25 | 36 |
row_1 | 0 | 8 | 18 | 30 | 44 | 60 | 78 |
row_2 | 0 | 15 | 32 | 51 | 72 | 95 | 120 |
row_3 | 0 | 22 | 46 | 72 | 100 | 130 | 162 |
col_0 | col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | |
---|---|---|---|---|---|---|---|
row_0 | 0.0 | NaN | 4.0 | NaN | 8.0 | NaN | 12.0 |
row_1 | 7.0 | NaN | 11.0 | NaN | 15.0 | NaN | 19.0 |
row_2 | 14.0 | NaN | 18.0 | NaN | 22.0 | NaN | 26.0 |
row_3 | 21.0 | NaN | 25.0 | NaN | 29.0 | NaN | 33.0 |
Иногда бывает нужно чтобы транслирование выполнялось не по столбцам а построчно, например, из значений элементов каждого столбца вычесть соответствующие значения серии:
Но если попытаться выполнить это, то мы получим далеко не то что нужно:
col_0 | col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | row_0 | row_1 | row_2 | row_3 | |
---|---|---|---|---|---|---|---|---|---|---|---|
row_0 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
row_1 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
row_2 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
row_3 | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN | NaN |
Что бы выполнить подобную операцию нужно воспользоваться методом sub() :
col_0 | col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | |
---|---|---|---|---|---|---|---|
row_0 | -4 | -3 | -2 | -1 | 0 | 1 | 2 |
row_1 | -4 | -3 | -2 | -1 | 0 | 1 | 2 |
row_2 | -4 | -3 | -2 | -1 | 0 | 1 | 2 |
row_3 | -4 | -3 | -2 | -1 | 0 | 1 | 2 |
Использование обычных чисел (скаляров) в выражениях, так же выполняется с выполнением трансляции по всему датафрейму:
col_0 | col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | |
---|---|---|---|---|---|---|---|
row_0 | 1 | 2 | 4 | 8 | 16 | 32 | 64 |
row_1 | 128 | 256 | 512 | 1024 | 2048 | 4096 | 8192 |
row_2 | 16384 | 32768 | 65536 | 131072 | 262144 | 524288 | 1048576 |
row_3 | 2097152 | 4194304 | 8388608 | 16777216 | 33554432 | 67108864 | 134217728 |
col_0 | col_1 | col_2 | col_3 | col_4 | col_5 | col_6 | |
---|---|---|---|---|---|---|---|
row_0 | 1 | 3 | 5 | 7 | 9 | 11 | 13 |
row_1 | 15 | 17 | 19 | 21 | 23 | 25 | 27 |
row_2 | 29 | 31 | 33 | 35 | 37 | 39 | 41 |
row_3 | 43 | 45 | 47 | 49 | 51 | 53 | 55 |
Логические операции, так же выполняются с выполнением транслирования:
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
row_0 | 0 | 0 | 0 | 1 |
row_1 | 2 | 0 | 0 | 0 |
row_2 | 0 | 1 | 1 | 1 |
row_3 | 2 | 1 | 0 | 0 |
row_4 | 2 | 1 | 1 | 0 |
row_5 | 2 | 2 | 2 | 1 |
row_6 | 1 | 2 | 2 | 1 |
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
row_0 | True | False | False | True |
row_1 | False | False | False | False |
row_2 | True | True | True | True |
row_3 | False | True | False | False |
row_4 | False | True | True | False |
row_5 | False | False | False | True |
row_6 | False | False | False | True |
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
row_0 | 2 | 1 | 2 | 0 |
row_1 | 2 | 2 | 2 | 0 |
row_2 | 1 | 1 | 1 | 2 |
row_3 | 0 | 1 | 1 | 2 |
row_4 | 1 | 1 | 1 | 0 |
row_5 | 2 | 2 | 2 | 2 |
row_6 | 2 | 0 | 1 | 0 |
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
row_0 | False | False | False | False |
row_1 | True | False | False | True |
row_2 | False | True | True | False |
row_3 | False | True | False | False |
row_4 | False | True | True | True |
row_5 | True | True | True | False |
row_6 | False | False | False | False |
Тоже самое касается и побитовых логических операций:
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
row_0 | False | False | False | True |
row_1 | False | True | False | False |
row_2 | False | False | False | True |
row_3 | False | False | False | False |
row_4 | True | True | False | False |
row_5 | True | False | False | True |
row_6 | False | False | True | True |
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
row_0 | 0 | 1 | 2 | 3 |
row_1 | 4 | 5 | 6 | 7 |
row_2 | 8 | 9 | 10 | 11 |
row_3 | 12 | 13 | 14 | 15 |
row_4 | 16 | 17 | 18 | 19 |
row_5 | 20 | 21 | 22 | 23 |
row_6 | 24 | 25 | 26 | 27 |
row_0 | row_1 | row_2 | row_3 | row_4 | row_5 | row_6 | |
---|---|---|---|---|---|---|---|
col_0 | 0 | 4 | 8 | 12 | 16 | 20 | 24 |
col_1 | 1 | 5 | 9 | 13 | 17 | 21 | 25 |
col_2 | 2 | 6 | 10 | 14 | 18 | 22 | 26 |
col_3 | 3 | 7 | 11 | 15 | 19 | 23 | 27 |
Все поэлементные функции NumPy могут выполняться над сериями и датафреймами, при условии, что они состоят из числовых значений:
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
row_0 | 1.0 | 2.0 | 4.0 | 8.0 |
row_1 | 16.0 | 32.0 | 64.0 | 128.0 |
row_2 | 256.0 | 512.0 | 1024.0 | 2048.0 |
row_3 | 4096.0 | 8192.0 | 16384.0 | 32768.0 |
row_4 | 65536.0 | 131072.0 | 262144.0 | 524288.0 |
row_5 | 1048576.0 | 2097152.0 | 4194304.0 | 8388608.0 |
row_6 | 16777216.0 | 33554432.0 | 67108864.0 | 134217728.0 |
Но это не значит, что датафреймы могут заменить собой массивы NumPy, так как они отличаются внутренней структурой и принципом индексации, например, сравните результат вычисления среднего значения для датафрейма с результатом вычислений для массива NumPy с теми же самыми элементами:
Тем не менее, серии полностью поддерживают универсальные функции NumPy, причем выравнивание индексов происходит перед применением данных функций:
Вывод на экран
Чаще всего датафреймы содержат очень много строк и столбцов, которые просто не могут поместиться на экран. В качестве примера, мы можем воспользоваться наборами данных из пакета Seaborn. Скорее всего вы работаете в дистрибутиве Anaconda или в Гугловском колабе, так что Seaborn наверняка у вас уже установлен. А если нет, то быстрее пересаживайтесь на анаконду и колаб!
total_bill | tip | sex | smoker | day | time | size | |
---|---|---|---|---|---|---|---|
0 | 16.99 | 1.01 | Female | No | Sun | Dinner | 2 |
1 | 10.34 | 1.66 | Male | No | Sun | Dinner | 3 |
2 | 21.01 | 3.50 | Male | No | Sun | Dinner | 3 |
3 | 23.68 | 3.31 | Male | No | Sun | Dinner | 2 |
4 | 24.59 | 3.61 | Female | No | Sun | Dinner | 4 |
. | . | . | . | . | . | . | . |
239 | 29.03 | 5.92 | Male | No | Sat | Dinner | 3 |
240 | 27.18 | 2.00 | Female | Yes | Sat | Dinner | 2 |
241 | 22.67 | 2.00 | Male | Yes | Sat | Dinner | 2 |
242 | 17.82 | 1.75 | Male | No | Sat | Dinner | 2 |
243 | 18.78 | 3.00 | Female | No | Thur | Dinner | 2 |
Это данные о чаевых в ресторане, которые состоят из семи столбцов и 244-х строк, понятно, что выводить все эти строки на экран не имеет смысла, т.к. получится очень длинная таблица. Что бы получить какое-то представление о таблице можно воспользоваться методом info() :
Да, чаще всего серии и датафреймы являются очень большими и их вывод просто не помещается на экран, поэтому, они выводятся в «урезанной» форме:
Что бы просмотреть их небольшой фрагмент, можно воспользоваться методами head() или tail() :
По умолчанию выводится всего 5 строк, но мы можем указать столько строк сколько нам нужно:
Атрибуты объектов Pandas
Допустим у нас есть следующий датафрейм:
A | B | C | D | |
---|---|---|---|---|
2020-01-01 | 0.291797 | 0.898429 | 0.471657 | 0.170232 |
2020-01-02 | 0.781077 | 0.088060 | 0.056392 | 0.110569 |
2020-01-03 | 0.949604 | 0.781641 | 0.281778 | 0.488396 |
2020-01-04 | 0.730843 | 0.055508 | 0.513162 | 0.109554 |
2020-01-05 | 0.703591 | 0.060644 | 0.542054 | 0.995164 |
Что бы получить доступ к его метаданным, таким как форма, названия столбцов и индексам строк, можно воспользоваться его атрибутами:
Объекты с именами столбцов и индексами строк являются неизменяемыми (немутирующими), так что если попробовать переименовать имя одного столбца или изменить индекс одной из строк, то мы увидим ошибку:
Но ничто нам не запрещает спокойно назначать датафреймам новые объекты columns и index :
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
2020-01-01 | 0.291797 | 0.898429 | 0.471657 | 0.170232 |
2020-01-02 | 0.781077 | 0.088060 | 0.056392 | 0.110569 |
2020-01-03 | 0.949604 | 0.781641 | 0.281778 | 0.488396 |
2020-01-04 | 0.730843 | 0.055508 | 0.513162 | 0.109554 |
2020-01-05 | 0.703591 | 0.060644 | 0.542054 | 0.995164 |
col_0 | col_1 | col_2 | col_3 | |
---|---|---|---|---|
id_0 | 0.291797 | 0.898429 | 0.471657 | 0.170232 |
id_1 | 0.781077 | 0.088060 | 0.056392 | 0.110569 |
id_2 | 0.949604 | 0.781641 | 0.281778 | 0.488396 |
id_3 | 0.730843 | 0.055508 | 0.513162 | 0.109554 |
id_4 | 0.703591 | 0.060644 | 0.542054 | 0.995164 |
В тоже время объекты Pandas (Series, DataFrame, Index, Columns) можно рассматривать как контейнеры для обычных массивов, которые содержат фактические данные и над которыми можно выполнять действия и вычисления. Основным типом используемых массивов являются массивы NumPy, но Pandas идет несколько дальше этих массивов и расширяет множество типов данных, которые могут в них содержаться.
Что бы преобразовать серии и их индексы в массивы NumPy можно воспользоваться их атрибутом array :
Иногда, знание таких тонкостей, очень сильно помогает. Например, вследствии того, что Pandas использует свои типы данных, корректное преобразование в массивы NumPy бывает просто невозможно без дополнительных манипуляций. Но мы пока не будем углубляться в эту тему и двинемся дальше.
Если нам нужен именно массив NumPy то можно воспользоваться методом Pandas to_numpy() или методом NumPy asarray() :
Если мы перобразуем эту серию в массив NumPy, то увидим что его данные будут типа object :
К данному типу преобразуется все что выходит за пределы базовых типов NumPy (строки, словари и многое другое тоже будет иметь тип данных object ). Конечно, это теперь массив NumPy который содержит информацию о дате и времени с указанием часового пояса. Но тем не менее, иногда нам все равно нужно получить именно массив NumPy с типом даты и времени. В этом случае мы можем воспользоваться параметром dtype :
С преобразованием датафреймов в массивы все немного сложнее. Если все столбцы датафрейма имеют единый тип данных, то метод to_numpy вернет массив с тем же самым типом данных:
Но если данные в столбцах разного типа, то тип данных результирующего масива будет преобразован к наиболее общему типу NumPy:
col_0 | col_1 | col_2 | col_3 | col_4 | |
---|---|---|---|---|---|
id_0 | 0.291797 | 0.898429 | 0.471657 | 0.170232 | a |
id_1 | 0.781077 | 0.088060 | 0.056392 | 0.110569 | b |
id_2 | 0.949604 | 0.781641 | 0.281778 | 0.488396 | c |
id_3 | 0.730843 | 0.055508 | 0.513162 | 0.109554 | d |
id_4 | 0.703591 | 0.060644 | 0.542054 | 0.995164 | e |