Подготовка табличных данных в среде Python инструментарием Pandas

Раздел: Data Science -> Pandas

Основные приёмы подготовки данных с помощью Pandas

Обработка пропущенных значений

Как эффективно заполнить пропуски в числовых и категориальных столбцах?

Наиболее универсальным решением является комбинация fillna() с разными стратегиями в зависимости от типа столбца. Для числовых данных часто применяют заполнение медианой, для категориальных – модой. Это сохраняет распределение и не вносит сильных смещений.

import pandas as pd import numpy as np df = pd.DataFrame({ 'A': [1, 2, np.nan, 4], 'B': ['x', 'y', None, 'z'] }) # заполнение числового столбца медианой df['A'] = df['A'].fillna(df['A'].median()) # заполнение категориального столбца модой df['B'] = df['B'].fillna(df['B'].mode()[0])

обработка больших данных python (обработка больших данных в python)

Типичная ошибка: попытка заполнить NaN значением, не соответствующим типу столбца (например, строкой в числовом столбце). Это приводит к ошибке TypeError. Решение – перед заполнением проверить тип данных через dtypes и применить соответствующую стратегию.

Как удалить строки с пропусками, если их доля мала?

Используется метод dropna() с параметрами axis=0 и how='any' (удаляет строку, если хотя бы один пропуск) или how='all' (только если все значения NaN).

df_clean = df.dropna(axis=0, how='any')

очистка данных python (очистка данных в python)

Проблема: при большом количестве пропусков удаление может привести к потере значительной части данных и смещению выборки. Следует оценивать долю пропусков перед удалением (df.isnull().sum() / len(df)).

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

Для последовательных данных с временной меткой хорошо работает interpolate(). По умолчанию используется линейная интерполяция, но можно задать метод method='quadratic' или method='spline' для более гладких кривых.

df_time = pd.DataFrame({ 'date': pd.date_range('2024-01-01', periods=5, freq='D'), 'value': [10, np.nan, 12, np.nan, 15] }).set_index('date') df_time['value'] = df_time['value'].interpolate()

Python подготовка данных (подготовка данных в python)

Важно: интерполяция работает только для числовых данных и требует упорядоченного индекса. Если индекс не отсортирован, необходимо выполнить sort_index() перед интерполяцией.

Удаление дубликатов

Как найти и удалить полные дубликаты строк?

Метод drop_duplicates() по умолчанию оставляет первое вхождение (keep='first'). Можно указать столбцы для проверки частичного дублирования через subset.

df = pd.DataFrame({'x': [1,2,1], 'y': ['a','b','a']}) df_no_dups = df.drop_duplicates(subset=['x'], keep='last')

работа с dataframe python (работа с dataframe в python)

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

Как выявить дубликаты без удаления?

Метод duplicated() возвращает булев массив. Его можно использовать для анализа: df[df.duplicated()] покажет все дублирующиеся строки.

duplicates_mask = df.duplicated(keep=False) # помечает все дубли, включая первое вхождение

Python работа с большими данными (работа с большими данными в python)

Преобразование типов данных

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

Используется astype() для приведения к числу и pd.to_datetime() для даты. Важно обрабатывать ошибки преобразования с помощью параметра errors='coerce', который заменяет некорректные значения на NaN.

df['price'] = df['price'].astype(float) # если есть загрязнения, сначала использовать pd.to_numeric df['date'] = pd.to_datetime(df['date'], errors='coerce')

структурированные данные python (структурированные данные в python)

Ошибка: при прямом astype(float) на строковом столбце с разделителями (например, '$10.50') возникает ValueError. Решение – предварительно очистить строку, удалив символы, или использовать pd.to_numeric с errors='coerce'.

Как преобразовать категориальный столбец в разреженный формат one-hot?

pd.get_dummies() создаёт бинарные столбцы для каждой категории. Для избежания мультиколлинеарности можно опустить первый уровень (drop_first=True).

df = pd.DataFrame({'cat': ['a','b','a','c']}) encoded = pd.get_dummies(df['cat'], prefix='cat')

генерация данных python (генерация данных в python)

Проблема: при большом количестве уникальных категорий (сотни) получается много столбцов, что увеличивает память. В таких случаях стоит рассмотреть использование Category типа Pandas или применение LabelEncoder из sklearn.

Фильтрация и выборка

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

Метод query() позволяет писать условия в строковом виде, что часто читаемее, чем логические маски. Поддерживает использование переменных через @.

threshold = 100 df_filtered = df.query('price > @threshold and quantity > 0')

Python код символа (код символа в python)

Типичная ошибка: использование несуществующих столбцов в условии вызывает UndefinedVariableError. Необходимо проверять имена столбцов через df.columns.

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

loc для меток индекса, iloc для целочисленных позиций. Для срезов указываются начальная и конечная границы.

df.loc[0:2] # строки с метками индекса 0,1,2 (если индекс целый) df.iloc[0:2] # строки с позициями 0 и 1 (последняя не включается)

код из файла python (код из файла python)

Объединение таблиц

Как объединить два набора данных по ключу?

merge() работает как SQL JOIN. Параметр how определяет способ: 'inner', 'left', 'right', 'outer'. Важно задавать ключи через left_on и right_on или on при одинаковых именах.

df1 = pd.DataFrame({'id': [1,2], 'val': ['a','b']}) df2 = pd.DataFrame({'id': [1,3], 'val2': ['c','d']}) merged = pd.merge(df1, df2, on='id', how='left')

обработка данных на python (обработка данных на python)

Типичная ошибка: дублирование ключей в одном из датафреймов приводит к декартову произведению. Следует проверять уникальность ключей через duplicated() или использовать агрегацию перед merge.

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

Для вертикального (по строкам) объединения используется pd.concat([df1, df2], axis=0), для горизонтального (по столбцам) – axis=1.

combined_rows = pd.concat([df1, df2], axis=0, ignore_index=True)

обработка символьных данных python (обработка символьных данных в python)

Проблема: при concat по строкам могут не совпадать столбцы – недостающие заполняются NaN. Это может быть неожиданностью. Лучше использовать join='inner' или обработать после.

Группировка и агрегация

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

Комбинация groupby() и transform() позволяет сохранить исходную структуру данных, добавив агрегированные значения в новый столбец.

df['avg_by_group'] = df.groupby('group')['value'].transform('mean')

Python преобразование в строку (преобразование в строку в python)

Ошибка: использование transform с функцией, которая не векторизована, может быть медленной. Для пользовательских функций применяют transform(lambda x: ...), но это менее производительно.

Как создать сводную таблицу с несколькими агрегациями?

pivot_table() принимает параметры values, index, columns, aggfunc. Можно задать список функций агрегации.

pivot = df.pivot_table(values='sales', index='region', columns='product', aggfunc=['sum', 'mean'])

Python как проверить строку (проверка строки в python)

Проблема: при наличии дублирующихся пар (index, columns) происходит ошибка или неопределённое поведение. Необходимо убедиться, что данные уникальны на уровне сводки, или задать aggfunc='first'.

Работа с категориальными переменными

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

pd.cut() разбивает интервал на заданное количество бинов или на конкретные границы. Метка может быть задана через labels.

df['age_group'] = pd.cut(df['age'], bins=[0, 18, 35, 60, 100], labels=['child','young','adult','senior'])

как работать с данными в python (работа с данными в python)

Типичная ошибка: если значение выходит за пределы bins, оно становится NaN. Необходимо расширять границы или использовать include_lowest=True.

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

Помимо one-hot, можно использовать LabelEncoder из sklearn или pd.factorize() для присвоения числовых кодов. Также sklearn.preprocessing.OrdinalEncoder для нескольких столбцов.

from sklearn.preprocessing import LabelEncoder le = LabelEncoder() df['cat_encoded'] = le.fit_transform(df['cat'])

Проблема: LabelEncoder не подходит для порядковых признаков (вносит произвольный порядок). Для порядковых лучше задать явное отображение словарём.

- Python dataframe строки (строки в dataframe pandas)
- столбец dataframe python (работа со столбцом dataframe в pandas)
- Python get url (получение url в python)

Расширенные примеры подготовки данных

Использование цепочек методов для очистки

Современный подход – объединять несколько операций в цепочку с помощью .pipe() или последовательно. Ниже показана полная предобработка датафрейма с пропусками, дубликатами и неверными типами.

Пример
import pandas as pd import numpy as np from sklearn.preprocessing import MinMaxScaler # Исходные данные df = pd.DataFrame({ 'id': [1, 2, 3, 4, 2], 'name': ['Alice', 'Bob', None, 'David', 'Bob'], 'age': [25, np.nan, 30, 28, 40], 'salary': ['50000', '60000', '75000', 'NaN', '62000'], 'department': ['IT', 'HR', 'IT', 'IT', 'HR'] }) # Определим функции очистки def clean_salary(df): df['salary'] = pd.to_numeric(df['salary'], errors='coerce') return df def fill_missing(df): df['age'] = df['age'].fillna(df['age'].median()) df['name'] = df['name'].fillna('Unknown') return df def remove_duplicates(df): return df.drop_duplicates(subset=['id'], keep='first').reset_index(drop=True) def encode_department(df): df = pd.get_dummies(df, columns=['department'], prefix='dept') return df # Цепочка обработки df_cleaned = (df .pipe(clean_salary) .pipe(fill_missing) .pipe(remove_duplicates) .pipe(encode_department) ) print(df_cleaned)
   id   name   age  salary  dept_HR  dept_IT 0   1  Alice  25.0   50000        0        1 1   2    Bob  28.0   60000        1        0 2   3  Unknown  30.0   75000        0        1 3   4  David  28.0     NaN        0        1

В результате удалён дубликат (id=2), пропущенные значения заполнены, зарплата приведена к числу, отдел закодирован one-hot. Пропуск в salary остался – его можно обработать далее, например, импутацией медианой.

Масштабирование числовых признаков

Для моделей, чувствительных к масштабу (SVM, kNN), необходимо нормализовать данные. Пример с MinMaxScaler и добавлением результата в датафрейм.

Пример
df_num = df_cleaned[['age', 'salary']].copy() scaler = MinMaxScaler() scaled = scaler.fit_transform(df_num) df_scaled = pd.DataFrame(scaled, columns=['age_scaled', 'salary_scaled']) df_final = pd.concat([df_cleaned, df_scaled], axis=1) print(df_final[['age', 'age_scaled', 'salary', 'salary_scaled']])
   age  age_scaled  salary  salary_scaled 0  25.0    0.000000   50000.0          0.000000 1  28.0    0.600000   60000.0          0.333333 2  30.0    1.000000   75000.0          0.833333 3  28.0    0.600000       NaN               NaN

Обратите внимание: NaN в salary_scaled – результат масштабирования, где входное значение было NaN. Это может потребовать дополнительной импутации перед масштабированием.

Обработка временных рядов с интерполяцией и resampling

Для данных с временной меткой часто требуется смена частоты. Пример почасового набора данных с пропусками.

Пример
dates = pd.date_range('2024-01-01', periods=8, freq='H') values = [1, np.nan, 3, 4, np.nan, 6, 7, 8] ts = pd.Series(values, index=dates, name='measure') # Ресемплинг до 2 часов с агрегацией среднего ts_resampled = ts.resample('2H').mean().interpolate() print('Исходный:', ts.values, sep='
') print('После ресемплинга и интерполяции:', ts_resampled.values, sep='
')
Исходный: [ 1. nan  3.  4. nan  6.  7.  8.] После ресемплинга и интерполяции: [1.  3.5 5.  7.5]

Интерполяция после агрегации даёт плавный переход между точками.

Объединение нескольких датафреймов с разными ключами

Пример сложного слияния с использованием pd.merge_asof для нечеткого совпадения по времени.

Пример
price = pd.DataFrame({'time': pd.to_datetime(['2024-01-01 10:00', '2024-01-01 10:15', '2024-01-01 10:30']), 'price': [100, 101, 102]}) trade = pd.DataFrame({'time': pd.to_datetime(['2024-01-01 10:10', '2024-01-01 10:20']), 'volume': [10, 20]}) # merge_asof подбирает ближайший момент из price к каждому trade merged = pd.merge_asof(trade, price, on='time', tolerance=pd.Timedelta('5min')) print(merged)
                 time  volume  price 0 2024-01-01 10:10:00      10  100.0 1 2024-01-01 10:20:00      20  101.0

Этот метод особенно полезен для финансовых данных, где торговые сделки не совпадают по времени с котировками.

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

Группировка с применением скользящего среднего внутри каждой группы.

Пример
df = pd.DataFrame({ 'group': ['A','A','A','B','B','B'], 'value': [1, 2, 3, 10, 11, 12] }) df['rolling_mean'] = df.groupby('group')['value'].transform(lambda x: x.rolling(2, min_periods=1).mean()) print(df)
  group  value  rolling_mean 0     A      1           1.0 1     A      2           1.5 2     A      3           2.5 3     B     10          10.0 4     B     11          10.5 5     B     12          11.5

Оконные функции полезны для создания признаков с временной или порядковой зависимостью.

Подготовка данных в Python - comments

En
Python подготовка данных (python)