Эффективная работа с DataFrame в 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