Эффективная работа с DataFrame в Pandas: методы и приёмы

Раздел: Обработка данных -> Библиотека pandas

Основные методы обработки данных в pandas

Как загрузить данные из CSV файла с учётом кодировки и разделителя?

Базовый способ: использование функции read_csv с минимальными параметрами. Этот метод подходит для стандартных CSV файлов с разделителем запятая и кодировкой UTF-8.

import pandas as pd
df = pd.read_csv('data.csv')

Python pandas index (работа с индексом dataframe в pandas)

После выполнения в переменной df будет объект DataFrame. Для быстрой проверки можно вывести первые строки: df.head().

Как загрузить файл с произвольным разделителем (например, точка с запятой)?

df = pd.read_csv('data.csv', sep=';')

работа с библиотекой pandas python (работа с библиотекой pandas в python)

Как указать кодировку, отличную от UTF-8 (например, CP1251)?

df = pd.read_csv('data.csv', encoding='cp1251')

Python pandas работа с данными (работа с данными в pandas)

Типичная ошибка: при несовпадении кодировки возникает исключение UnicodeDecodeError. Решение – явно указать правильную кодировку. Также возможна проблема с BOM (метка порядка байтов) в начале файла. В таких случаях помогает параметр encoding='utf-8-sig'.

df = pd.read_csv('data.csv', encoding='utf-8-sig')

Как быстро оценить структуру и типы данных DataFrame?

Основной подход: комбинация методов info() и describe().

df.info()
df.describe()

info() показывает количество непустых значений и тип каждого столбца. describe() выдаёт описательную статистику для числовых столбцов.

Как получить только количество пропусков по каждому столбцу?

df.isnull().sum()

Как посмотреть уникальные значения в столбце?

df['column'].unique()

Проблема: если в DataFrame много столбцов, вывод info() может быть нечитаемым. Решение – применить df.info(verbose=False) или выборочно проверять только нужные столбцы.

Как выбрать подмножество строк и столбцов по условию и индексу?

Основной способ: использование loc для доступа по меткам и iloc по позициям.

# Выбрать строки с 5 по 10 (позиции) и столбцы 'Name' и 'Age'
df.iloc[5:11, [0, 2]]
# Выбрать строки, где значение столбца 'Age' больше 25, и столбцы 'Name', 'Salary'
df.loc[df['Age'] > 25, ['Name', 'Salary']]

Как выбрать столбцы по условию на их имена (например, все столбцы, начинающиеся с 'col')?

df.loc[:, df.columns.str.startswith('col')]

Как комбинировать логические условия (И, ИЛИ)?

df[(df['Age'] > 25) & (df['City'] == 'Moscow')]  # И
df[(df['Age'] > 25) | (df['Salary'] < 50000)]  # ИЛИ

Распространённая ошибка: забыть скобки вокруг условий. Без скобок операции приоритета могут привести к непредсказуемому результату. Всегда оборачивайте каждое условие в скобки.

Как сгруппировать данные и вычислить агрегированные показатели?

Основной подход: использование groupby с одной или несколькими функциями агрегации.

# Средняя зарплата по городам
df.groupby('City')['Salary'].mean()
# Несколько агрегаций одновременно
df.groupby('City')['Salary'].agg(['mean', 'sum', 'count'])

Как применить разные агрегации к разным столбцам?

df.groupby('City').agg({'Salary': 'mean', 'Age': 'max', 'Name': 'count'})

Как сгруппировать по нескольким столбцам?

df.groupby(['City', 'Department'])['Salary'].mean()

Проблема: после группировки индекс становится мультииндексом, что может затруднить дальнейшую работу. Решение – сбросить индекс с помощью .reset_index() или использовать параметр as_index=False.

df.groupby('City', as_index=False)['Salary'].mean()

Как объединить две таблицы с разными ключами?

Основной способ: функция pd.merge() с явным указанием столбца для соединения.

df_merged = pd.merge(df_left, df_right, on='id', how='inner')

Параметр how определяет тип соединения: inner, left, right, outer.

Как объединить по разным именам столбцов?

pd.merge(df_left, df_right, left_on='id_left', right_on='id_right')

Как объединить по индексу?

pd.merge(df_left, df_right, left_index=True, right_on='id')

Ошибка: при наличии дублирующихся ключей в обеих таблицах может произойти декартово произведение. Чтобы избежать, следует предварительно удалить дубликаты или использовать соединение с уникализацией.

Как обработать пропущенные значения (NaN)?

Основной подход: замена пропусков на среднее или медиану для числовых столбцов.

df['Salary'].fillna(df['Salary'].median(), inplace=True)

Также можно удалять строки с пропусками: df.dropna(inplace=True).

Как заполнить пропуски предыдущим значением (forward fill)?

df.fillna(method='ffill', inplace=True)

Как заполнить пропуски для разных столбцов разными значениями?

values = {'Salary': df['Salary'].mean(), 'Age': df['Age'].median()}
df.fillna(value=values, inplace=True)

Проблема: при использовании inplace=True операция изменяет исходный DataFrame, что может быть опасно. Рекомендуется присваивать результат новой переменной или использовать inplace=False (по умолчанию).

Как создать новый столбец на основе существующих?

Основной способ: присваивание нового столбца с помощью вычислений.

df['Bonus'] = df['Salary'] * 0.1

Как создать столбец с условной логикой?

df['Category'] = ['High' if x > 50000 else 'Low' for x in df['Salary']]

Как использовать функцию apply для более сложных преобразований?

def categorize(age):
    if age < 30: return 'Young'
    elif age < 50: return 'Middle'
    else: return 'Senior'
df['AgeGroup'] = df['Age'].apply(categorize)

Ошибка производительности: применение пользовательских функций через apply может быть медленным на больших данных. Альтернатива – векторизованные операции, например, np.where или метод pandas.cut.

Дополнительные примеры продвинутой обработки данных

Сложная группировка с несколькими агрегациями и пользовательскими функциями

Пример
import pandas as pd

df = pd.DataFrame({
    'City': ['Moscow', 'Moscow', 'SPb', 'SPb', 'Moscow'],
    'Department': ['Sales', 'IT', 'Sales', 'IT', 'IT'],
    'Salary': [70000, 90000, 65000, 85000, 95000],
    'Age': [30, 25, 35, 40, 28]
})

# Группировка по городу и отделу с вычислением нескольких статистик
grouped = df.groupby(['City', 'Department']).agg(
    avg_salary=('Salary', 'mean'),
    max_age=('Age', 'max'),
    count=('Salary', 'count')
).reset_index()
print(grouped)
     City Department  avg_salary  max_age  count
0  Moscow         IT    92500.0       28      2
1  Moscow      Sales    70000.0       30      1
2     SPb         IT    85000.0       40      1
3     SPb      Sales    65000.0       35      1

Объединение таблиц с разными типами соединений и обработкой дубликатов

Пример
left = pd.DataFrame({'id': [1, 2, 3, 4], 'name': ['Alice', 'Bob', 'Charlie', 'David']})
right = pd.DataFrame({'id': [3, 4, 5, 6], 'salary': [70000, 80000, 90000, 95000]})

# Outer join с сохранением всех записей
merged = pd.merge(left, right, on='id', how='outer', indicator=True)
print(merged)
   id     name   salary      _merge
0   1    Alice      NaN   left_only
1   2      Bob      NaN   left_only
2   3  Charlie  70000.0        both
3   4    David  80000.0        both
4   5      NaN  90000.0  right_only
5   6      NaN  95000.0  right_only

Условная замена значений с использованием np.where

Пример
import numpy as np

df['HighSalary'] = np.where(df['Salary'] > 80000, 'Yes', 'No')
print(df[['Salary', 'HighSalary']])
   Salary HighSalary
0   70000         No
1   90000        Yes
2   65000         No
3   85000        Yes
4   95000        Yes

Создание сводной таблицы (pivot_table) с несколькими значениями и агрегациями

Пример
pivot = df.pivot_table(
    values='Salary',
    index='City',
    columns='Department',
    aggfunc='mean',
    fill_value=0
)
print(pivot)
Department     IT     Sales
City                       
Moscow      92500.0  70000.0
SPb         85000.0  65000.0

Применение функции к каждой строке с помощью apply (оси 1)

Пример
df['Description'] = df.apply(
    lambda row: f"{row['Name']} from {row['City']} earns {row['Salary']}",
    axis=1
)
print(df['Description'])
0    Alice from Moscow earns 70000
1      Bob from Moscow earns 90000
2    Charlie from SPb earns 65000
3      David from SPb earns 85000
4     David from Moscow earns 95000
Name: Description, dtype: object

Работа с данными в pandas - comments

En
Python pandas работа с данными (python)