В наше время эффективное взаимодействие с различными показателями и информацией играет важную роль в принятии решений, управлении и во многих других сферах. Для эффективной работы необходимы гибкие и надежные инструменты. Об одном из таких поговорим в этой статье. Библиотека Pandas для Python — это одно из самых популярных, сильных и эффективных средств для обработки и анализа данных в языке программирования Python.
Что такое Pandas: описание библиотеки
Библиотека Pandas — это открытый программный продукт, разработанный специально для проведения различных операций с данными, среди которых чтение, запись, фильтрация, агрегирование, визуализация и группировка. Работать можно со многими типами данных — целыми числами, числами с плавающей запятой, списками, булевыми значениями, категориальными данными, datetime, сложными числами и недопустимыми значениями (в том числе NaN, NaT). Помимо этого, библиотека поддерживает и другие форматы данных.
Также важно отметить, что есть возможность интеграции с другими широко используемыми библиотеками для Python, например c Matplotlib, что позволяет значительно расширить их функциональность.
Основные преимущества библиотеки — производительность, гибкость и простота использования. В Pandas работа с данными становится эффективнее и удобнее для специалиста.
Для чего нужна библиотека Pandas
Описание библиотеки Pandas уже дает понимание того, что с помощью нее специалист может решить широкий спектр самых разнообразных задач на языке Python. Рассмотрим основные операции, которые можно осуществить, используя Pandas:
- обработка информации (фильтрация, группировка, объединение и агрегирование);
- чтение и запись (поддерживаемые форматы — CSV, Excel, SQL, HTML и другие);
- манипуляция структурой;
- визуализация (создание разных видов графиков);
- подготовка для ML (нормализация, масштабирование).
Как установить Pandas?
Установка библиотеки Pandas осуществляется с помощью стандартного инструмента установки и управления пакетами Python — менеджера пакетов pip. В командной строке необходимо ввести:
pip install pandas
Для пользователей Anaconda:
conda install -c conda-forge pandas
После этого будет проведена установка последней версии библиотеки и всех необходимых зависимостей. Для того чтобы импортировать библиотеку в проект, необходима команда. Как правило, импортируют ее под псевдонимом pd, соответственно, использовать ее тоже нужно под этим псевдонимом:
import pandas as pd
Основные функции для работы с Pandas
DataFrame и Series
Работа с библиотекой Pandas подразумевает взаимодействие с двумя основными элементами. Именно они обеспечивают возможность удобно хранить и манипулировать разными структурами. Рассмотрим их по отдельности.
- DataFrame (df) — это двумерная таблица данных, состоящая из строк и столбцов. Каждая строка и столбец имеют свои индексы, по которым к ним можно обращаться. По умолчанию индексы создаются автоматически, но при необходимости их можно задать вручную. В одной такой таблице можно хранить разные типы данных: числа, строки и другие. Объект предоставляет множество возможностей для проведения операций, например для фильтрации или сортировки.
Пример создания df из словаря:
# Импортируем библиотеку
import pandas as pd
# Объявляем словарь data с необходимыми элементами
data = {
'Name': ['John', 'Anna', 'Jack', 'Helen'],
'Age': [28, 24, 35, 32],
'City': ['New York', 'Paris', 'Berlin', 'London']
}
# Создаем df из словаря
df = pd.DataFrame(data)
# Либо создаем df из словаря с заданными метками индекса
df = pd.DataFrame(data, index=['a', 'b', 'c', 'd'])
# При необходимости индексы можно сбросить
df_reset = df.reset_index()
# Можно переименовать столбцы
df_renamed = df.rename(columns={'Name': 'Full Name', 'Age': 'Years'})
# И индексы
df_renamed_index = df.rename(index={'a': 'A', 'b': 'B'})
# Сброс индексов осуществляется с помощью reset_index() и его основных параметров (необязательных):
# drop — определяет, нужно ли удалить текущий индекс, по умолчанию False
# inplace — определяет, нужно ли изменить df, не создавая при этом новый, по умолчанию False
# level — определяет, до какого уровня нужно сбросить индексы
df.reset_index(drop=True, inplace=True)
# Можно сбрасывать часть индексов и переименовывать несколько иначе, здесь лишь основные способы
#Объединение двух df
combined_df = pd.concat([df1, df2])
В таком случае каждый ключ станет именем столбца, а значения — строками этих столбцов.
Пример создания из списка списков:
# Импортируем библиотеку
import pandas as pd
# Объявляем data с необходимыми элементами
data = [['John', 28, 'New York'], ['Anna', 24, 'Paris'], ['Jack', 35, 'Berlin'], ['Helen', 32, 'London']]
# Создаем df из списка списков
df = pd.DataFrame(data, columns=['Name', 'Age', 'City'])
Визуализировать полученную таблицу можно следующим образом (первый столбец — это индекс):
Name | Age | City | |
0 | John | 28 | New York |
1 | Anna | 24 | Paris |
2 | Jack | 35 | Berlin |
3 | Helen | 32 | London |
- Series — это одномерный массив, в котором могут содержаться разные типы данных. К элементам такого массива можно обращаться по именам, а не по их числовым индексам, если эти имена объявить. Создание такого массива позволяет проводить математические операции, агрегирование и другие манипуляции.
Пример создания объекта из списка значений:
import pandas as pd
# Создаем объект из списка [1, 2, 3, 4, 5]
s = pd.Series([1, 2, 3, 4, 5], index=['a', 'b', 'c', 'd', 'e'])
Таким образом, к элементам можно будет обращаться по индексам, которые были объявлены (к элементу «1» — по индексу «a»).
Работа со строками
Взаимодействие со строками в Python можно разделить на 4 вида операций: добавление, удаление, изменение строки, а также применение методов для строк. В основных элементах библиотеки эти операции выполняются по-разному. Дадим описание для обоих видов элементов.
- Для DataFrame:
# За основу возьмем df, созданный в примере выше
# Добавление новой строки
df.loc[len(df)] = ['Alice', 29, 'San Francisco']
# Изменение значения элемента (изменяем строку столбца 'Age' с индексом 1)
df.at[1, 'Age'] = 25
# Удаление строки (в качестве аргумента указываем индекс строки)
df = df.drop(2)
# Преобразование строкового столбца 'Name' в верхний регистр
df['Name_upper'] = df['Name'].str.upper()
# Поиск подстроки
df['Contains_a'] = df['Name'].str.contains('a')
# Замена подстроки (в данном случае меняем символы 'a' на 'o')
df['Replaced'] = df['Name'].str.replace('a', 'o')
# Разбиение строк
df['Split'] = df['Name'].str.split('a')
# Объединение строк в столбце 'Name'
joined_names = df['Name'].str.cat(sep=', ')
- Для Series:
# За основу возьмем s, созданный в примере выше
# Добавление элемента
s = s.append(pd.Series([6], index=['f']))
# Изменение значения элемента по индексу
s.at['b'] = 20
# Удаление элемента по индексу
s = s.drop('c')
# Преобразование значений в строки (необходимо, т. к. у нас числовые значения)
s_str = s.astype(str)
# Преобразование в верхний регистр
s_upper = s_str.str.upper()
# Поиск подстроки (в данном случае фактически ищем строку, а не подстроку)
contains_2 = s_str.str.contains('2')
# Замена подстроки
replaced = s_str.str.replace('2', '3')
# Разбиение строк
split = s_str.str.split('2')
# Объединение строк
s_joined = s_str.str.cat(sep=', ')
Стоит заметить, что способов взаимодействия со строками на самом деле гораздо больше, здесь мы рассмотрели лишь часть.
Доступ по индексу в DataFrame
В этом разделе речь пойдет об основных методах для доступа по индексу: .loc и .iloc.
- .loc — это наиболее удобный способ получить доступ, если у нас есть метки индекса строк и столбцов (меткой столбца считаем его текстовое название, например Name):
# За основу возьмем df с метками индексов из примера
# Доступ к нескольким строкам по меткам индексов
rows_bd = df.loc[['b', 'd']]
print(rows_bd)
# Результат
Name Age City
b Anna 24 Paris
d Helen 32 London
# Доступ к одному элементу по метке строки и столбца
age_b = df.loc['b', 'Age']
# Доступ к нескольким элементам по меткам строк и столбцов
ages = df.loc[['a', 'c'], 'Age']
# Доступ по меткам строк и столбцов
subset = df.loc[['a', 'd'], ['Name', 'City']]
print(subset)
# Результат
Name City
a John New York
d Helen London
- .iloc же предназначен для использования в случаях, когда индексы элементов представлены числовыми значениями:
# За основу возьмем df без меток индексов из примера
# Доступ к нескольким строкам по позициям индексов
rows_1_3 = df.iloc[[1, 3]]
print(rows_1_3)
# Результат
Name Age City
1 Anna 24 Paris
3 Helen 32 London
# Доступ к одному элементу по позициям строки и столбца
age_1 = df.iloc[1, 1]
# Доступ к нескольким элементам по позициям строк и столбцов
ages = df.iloc[[0, 2], 1]
# Доступ по позициям строк и столбцов
subset = df.iloc[[0, 3], [0, 2]]
print(subset)
# Результат
Name City
0 John New York
3 Helen London
Чтение и запись данных
Чтение и запись — среди самых значимых возможностей библиотеки. Pandas предоставляет возможность обрабатывать множество форматов, здесь же мы затронем основные. Для описания проведения таких манипуляций рассмотрим следующие примеры:
# Чтение CSV файла
df_csv = pd.read_csv('имя_файла.csv')
# Чтение Excel файла
df_excel = pd.read_excel('имя_файла.xlsx', sheet_name='имя_листа')
# Для чтения SQL баз данных необходима библиотека для соединения с базой, например SQLAlchemy
from sqlalchemy import create_engine
# Создаем соединение с БД
engine = create_engine('sqlite:///database.db')
# Чтение данных из SQL таблицы
df_sql = pd.read_sql('SELECT * FROM table_name', engine)
# Чтение данных из HTML таблицы
url = 'https://example.com/table.html'
dfs_html = pd.read_html(url)
# Чтение JSON файла
df_json = pd.read_json('имя_файла.json')
# Чтение данных из буфера обмена
df_clipboard = pd.read_clipboard()
При необходимости вывести результат используется стандартная конструкция print(). Также можно вывести первые 5 строк, используя следующую конструкцию: df.head(). Например, print(df_csv.head()).
Запись файлов рассмотрим также на примерах:
# Запись в CSV файл
# Указываем index=False, чтобы индексы df не записывались в отдельный столбец таблицы
df.to_csv('имя_файла.csv', index=False)
# Запись в Excel файл
df.to_excel('имя_файла.xlsx', sheet_name='Sheet1', index=False)
# Также нужна библиотека для соединения с БД
from sqlalchemy import create_engine
# Создаем соединение с БД
engine = create_engine('sqlite:///database.db')
# Запись в SQL таблицу
df.to_sql('table_name', engine, index=False, if_exists='replace')
# Запись в JSON файл
df.to_json('имя_файла.json')
# Запись в буфер обмена
df.to_clipboard()
Именно эти приемы библиотеки обеспечивают удобство и гибкость библиотеки при работе с разными форматами.
Группировка, фильтрация и агрегирование данных
При взаимодействии с большим объемом информации неизбежно возникает потребность в том, чтобы каким-то образом ее упорядочить. В таком случае необходимо прибегнуть к подходам, описание которых будет дано в этой части статьи: группировка, фильтрация и агрегирование.
- Группировка — это процесс разделения элементов по одному или нескольким заданным критериям, часто это предварительный этап перед применением агрегации. Используется для этого метод groupby().
Пример:
import pandas as pd
# Создаем словарь с нужными элементами
data = {
'Name': ['John', 'Anna', 'Jack', 'Helen', 'Paul', 'Lisa'],
'Age': [28, 24, 35, 32, 45, 38],
'City': ['New York', 'Paris', 'Berlin', 'London', 'New York', 'Berlin'],
'Salary': [70000, 80000, 120000, 95000, 65000, 110000]
}
df = pd.DataFrame(data)
# Группировка по одному столбцу, в данном случае — 'City'
grouped = df.groupby('City')
# Группировка по нескольким столбцам
grouped_2 = df.groupby(['City', 'Salary'])
- Фильтрация — это процесс выбора элементов на основе заданных условий. Здесь могут пригодиться описанные ранее .loc и .iloc, а также логические условия.
Пример:
# За основу берем df из примера группировки
# Фильтрация по условию, выбираем тех, кто старше 30
filtered = df[df['Age'] > 30]
print(filtered)
# Результат
Name Age City Salary
2 Jack 35 Berlin 120000
3 Helen 32 London 95000
4 Paul 45 New York 65000
5 Lisa 38 Berlin 110000
# Фильтрация с .loc, выбираем тех, чей город — Paris
filtered_paris = df.loc[df['City'] == 'Paris']
print(filtered_paris)
Name Age City Salary
1 Anna 24 Paris 80000
# Фильтрация по нескольким условиям
filtered_complex = df[(df['Age'] > 30) & (df['City'] == 'New York')]
print(filtered_complex)
Name Age City Salary
4 Paul 45 New York 65000
- Агрегирование — это процесс выполнения различных операций, которые строятся на основе всего набора элементов. Агрегирование позволяет нужным образом обработать большие объемы информации. Осуществляется процесс путем применения функций, их достаточно много, здесь мы рассмотрим основные:
# За основу берем grouped из примера группировки
# mean() — вычисление среднего арифметического значения
# Так как у нас группировка по городам, вычислим средний возраст по городам
print(grouped['Age'].mean())
# Результат
City
Berlin 36.5
London 32.0
New York 36.5
Paris 24.0
Name: Age, dtype: float64
# sum() — вычисление суммы всех значений в группе
# Вычислим сумму зарплат по городам
print(grouped['Salary'].sum())
# count() — подсчет количества непустых значений в группе
# Используется для определения размера группы
# Найдем количество имен в каждом городе
print(grouped['Name'].count())
# Результат
City
Berlin 2
London 1
New York 2
Paris 1
Name: Name, dtype: int64
# min() и max() — поиск минимального и максимального значения в группе
# Найдем минимальный возраст по городам
print(grouped['Age'].min())
# Найдем максимальный возраст по городам
print(grouped['Age'].max())
# median() — вычисление медианного значения в группе
# Найдем медианный возраст по городам
print(grouped['Age'].median())
# std() — вычисление стандартного отклонения
print(grouped['Age'].std())
# var() — вычисление дисперсии
print(grouped['Age'].var())
# prod() — вычисление произведения всех значений в группе
# Используется редко, как правило, для решения экономических задач или при подсчете вероятностей
print(grouped['Age'].prod())
# first() и last() — поиск первого и последнего элемента группы
print(grouped['Age'].first())
print(grouped['Age'].last())
# describe() — возвращает сводную статистику
print(grouped['Age'].describe())
# Результат
count mean std min 25% 50% 75% max
City
Berlin 2.0 36.5 2.121320 35.0 35.75 36.5 37.25 38.0
London 1.0 32.0 NaN 32.0 32.00 32.0 32.00 32.0
New York 2.0 36.5 12.020815 28.0 32.25 36.5 40.75 45.0
Paris 1.0 24.0 NaN 24.0 24.00 24.0 24.00 24.0
# agg() — позволяет использовать несколько агрегирующих функций
# Найдем средний, минимальный и максимальный возраст, суммарную и среднюю зарплату по городам
agg_funcs = grouped.agg({
'Age': ['mean', 'min', 'max'],
'Salary': ['sum', 'mean']
})
print(agg_funcs)
# Результат
Age Salary
mean min max sum mean
City
Berlin 36.5 35 38 230000 115000.0
London 32.0 32 32 95000 95000.0
New York 36.5 28 45 135000 67500.0
Paris 24.0 24 24 80000 80000.0
Применять все это можно как к сгруппированным элементам, так и к несгруппированным.
Сводные таблицы в Pandas
Сводные таблицы также являются очень полезным инструментом анализа, так как позволяют сгруппировать элементы по одному или нескольким признакам/параметрам. Можно сказать, что это тоже способ агрегации и суммирования данных. Чаще всего сводные таблицы используются, когда необходимо выявить статистические показатели, проанализировать изменения данных по времени или их распределение по категориям. Для создания сводных таблиц применяется метод pd.pivot_table(). Рассмотрим тему создания сводных таблиц на следующем примере:
import pandas as pd
# Создаем словарь sales_data с необходимыми элементами
sales_data = {
'Date': ['2024-05-01', '2024-05-01', '2024-05-02', '2024-05-02', '2024-05-03'],
'Product': ['A', 'B', 'A', 'B', 'A'],
'Sum': [1000, 1500, 2000, 1800, 1200]
}
sales_df = pd.DataFrame(sales_data)
# Создаем сводную таблицу
# Параметры pd.pivot_table(): data - исходный df
# values — столбец или столбцы для агрегирования
# index — ключи для группировки по индексу
# columns — ключи для группировки столбцов
# aggfunc — функция, которую будем применять, в данном случае sum
# Метод имеет и другие параметры, выше указаны основные
pivot_table = pd.pivot_table(sales_df, values='Sum', index='Date', columns='Product', aggfunc='sum')
print(pivot_table)
# Получим такой результат
Product A B
Date
2024-05-01 1000.0 1500.0
2024-05-02 2000.0 1800.0
2024-05-03 1200.0 NaN
Визуализация данных в Pandas
Визуализация — это важная часть анализа, так как именно она позволяет интерпретировать сложные числовые или текстовые элементы, а также проще выявить тенденции. Как правило, под визуализацией подразумевается построение различных графиков и диаграмм. Рассмотрим способы создания некоторых из них. Для реализации нам понадобится интеграция с библиотекой Matplotlib для Python и основной метод .plot(), который предназначается для построения графиков.
- Линейные диаграммы
import pandas as pd
import matplotlib.pyplot as plt
data = {
'Month': ['Jan', 'Feb', 'Mar', 'Apr', 'May'],
'Sales': [200, 220, 250, 270, 300]
}
df = pd.DataFrame(data)
# Строим линейный график: указываем значения осей и kind='line'
df.plot(x='Month', y='Sales', kind='line', title='Monthly Sales', xlabel='Month', ylabel='Sales')
# Выводим результат
plt.show()
- Столбчатые диаграммы
# За основу взят df из примера линейной диаграммы
# Строим столбчатую диаграмму, kind='bar'
df.plot(x='Month', y='Sales', kind='bar', title='Monthly Sales', xlabel='Month', ylabel='Sales')
plt.show()
- Диаграммы рассеяния
# За основу взят df из примера линейной диаграммы
# Строим диаграмму рассеяния, kind='scatter'
df.plot(x='Sales', y='Month', kind='scatter', title='Monthly Sales', xlabel='Sales', ylabel='Month')
plt.show()
- Круговые диаграммы
# За основу взят df из примера линейной диаграммы
# Для построения круговой диаграммы указываем kind='pie'
df.set_index('Month').plot(kind='pie', y='Sales', autopct='%1.1f%%', title='Just for fun')
plt.show()
Подводя итог этой статьи, построим график (столбчатую диаграмму) средней зарплаты по городам, используя df из примера группировки. Это одна из самых простых иллюстраций комбинированного применения рассмотренной сегодня информации о Pandas для Python.
# Последовательно группируем df по городам, находим среднюю зарплату и строим диаграмму
df.groupby('City')['Salary'].mean().plot(kind='bar')
plt.show()