Skip to content

10. Feature Engineering: кодирование категориальных признаков и метод .apply() ​

Подготовка текста и категорий к подаче в нейросети ​

Проблема текстовых признаков в машинном обучении ​

Математические алгоритмы, процессоры общего назначения и тензорные ядра видеокарт (GPU) физически не умеют умножать или складывать буквы и текстовые строки. Компьютер оперирует исключительно числами. Если в вашем датасете присутствует категориальный (текстовый) признак — например, тип используемого устройства ["ios", "android", "windows"] или жанр фильма, — его необходимо перевести в строгий числовой формат. Этот этап называется Feature Engineering (конструирование признаков).

Алгоритм One-Hot Encoding (Прямое двоичное кодирование) ​

Самым популярным и безопасным способом оцифровать текстовые категории в глубоком обучении является алгоритм One-Hot Encoding (кодирование «1 из N»). Он берет столбец с категориями и превращает его в несколько новых независимых бинарных (булевых) столбцов — по одному на каждую уникальную категорию.

На пересечении строки и новой колонки ставится единица (1 или True), если объект относился к этой категории, и ноль (0 или False) во всех остальных случаях. Для реализации этого алгоритма в Pandas используется быстрая векторная функция pandas.get_dummies(dataframe, columns).

python
import pandas

raw_users = {
    "user_id": [101, 102, 103],
    "device_os": ["ios", "android", "ios"]
}
df_users = pandas.DataFrame(raw_users)

# Running One-Hot Encoding over the categorical column
df_encoded = pandas.get_dummies(df_users, columns=["device_os"])

print(df_encoded)
# Outputs a numeric matrix format:
#    user_id  device_os_android  device_os_ios
# 0      101              False           True
# 1      102               True          False
# 2      103              False           True

Кастомные трансформации через .apply() ​

Метод .apply() и лямбда-функции lambda x: ... ​

Иногда векторизованных ufuncs-функций общего назначения не хватает для решения специфических AI-задач. Например, вам нужно очистить текст от спецсимволов, посчитать длину каждого входящего предложения (Sequence Length) или применить сложную кастомную формулу масштабирования фичей.

Для выполнения произвольных преобразований над элементами столбца в Pandas используется мощнейший инструмент — метод series.apply(function). В качестве аргумента он принимает функцию (часто лаконичную безымянную lambda), которую Pandas последовательно применяет к каждой ячейке.

python
import pandas

df_text = pandas.DataFrame({"raw_review": ["Great AI model", "Terrible error inside code"]})

# Using .apply() with lambda to compute sequence words length for each row object
df_text["sequence_length"] = df_text["raw_review"].apply(lambda x: len(x.split()))

print(df_text)
# Outputs:
#                    raw_review  sequence_length
# 0              Great AI model                3
# 1  Terrible error inside code                4

Упражнения базовые (5 шт) (только с опорой на объясненную в данном уроке теорию) ​

1. Бинарное кодирование классов One-Hot Encoding ​

Задача: Дан DataFrame df_classes = pandas.DataFrame({"target_class": ["cat", "dog", "cat"]}). С помощью функции pandas.get_dummies() преобразуйте этот категориальный столбец в бинарную матрицу признаков. Выведите результат.

Посмотреть решение
python
import pandas

df_classes = pandas.DataFrame({"target_class": ["cat", "dog", "cat"]})

# Executing direct one-hot encoding translation
encoded_df = pandas.get_dummies(df_classes, columns=["target_class"])
print(encoded_df)

2. Кастомное вычисление длины строк признака ​

Задача: Создайте Series из текстовых категорий sentences = pandas.Series(["low", "medium", "critical_high"]). С помощью метода .apply() и лямбда-функции преобразуйте этот столбец в вектор целых чисел, отражающих количество символов в каждом слове. Выведите результат.

Посмотреть решение
python
import pandas

sentences = pandas.Series(["low", "medium", "critical_high"])

# Computing character counts for each text string item
char_counts = sentences.apply(lambda text: len(text))
print(char_counts)  # Outputs: [3, 6, 13]

3. Бинарный маппинг признаков через лямбду ​

Задача: Дан числовой столбец df_metrics = pandas.DataFrame({"loss": [0.85, 0.12, 0.44]}). Напишите кастомную трансформацию через .apply(), которая ставит 1, если значение "loss" больше 0.4, и 0 в противном случае. Результат сохраните в новую колонку "loss_flag".

Посмотреть решение
python
import pandas

df_metrics = pandas.DataFrame({"loss": [0.85, 0.12, 0.44]})

# Using ternary logic inside lambda expression mapping pipeline
df_metrics["loss_flag"] = df_metrics["loss"].apply(lambda x: 1 if x > 0.4 else 0)
print(df_metrics)

4. Приведение текста к нижнему регистру для NLP ​

Задача: Имеется столбец текстовых признаков df_nlp = pandas.DataFrame({"tokens": ["BERT", "Transformer", "GPT"]}). Примените метод .apply() к столбцу "tokens", чтобы перевести все строки в нижний регистр с помощью стандартного строкового метода .lower(). Выведите измененную таблицу.

Посмотреть решение
python
import pandas

df_nlp = pandas.DataFrame({"tokens": ["BERT", "Transformer", "GPT"]})

# Normalizing text layout casing inside the tokens feature track
df_nlp["tokens"] = df_nlp["tokens"].apply(lambda s: s.lower())
print(df_nlp)

5. Принудительное бинарное кодирование с переводом в int ​

Задача: Функция pandas.get_dummies() по умолчанию возвращает булевы типы (True/False). Повторите кодирование для таблицы df_classes = pandas.DataFrame({"target_class": ["cat", "dog"]}), но принудительно добавьте параметр dtype=int, чтобы на выходе получились математические нули и единицы. Выведите результат.

Посмотреть решение
python
import pandas

df_classes = pandas.DataFrame({"target_class": ["cat", "dog"]})

# Forcing discrete numerical outputs instead of booleans flags
integer_encoded_df = pandas.get_dummies(df_classes, columns=["target_class"], dtype=int)
print(integer_encoded_df)

Упражнения смешанные (5 шт) (включают материал прошлых уроков) ​

6. Загрузка CSV-файла и One-Hot кодирование признаков с оценкой RAM ​

Задача: Считайте датасет из файла "raw_logs.csv" (Урок 8). Выполните операцию One-Hot Encoding для текстового столбца "user_status" с принудительным выставлением типа данных dtype=int (Урок 10). Для полученного закодированного DataFrame выведите прецизионную оценку занимаемой памяти в байтах методом .memory_usage(deep=True) (Урок 5).

Посмотреть решение
python
import pandas

# Step 1: Loading raw dataset table from disk (Lesson 8)
source_df = pandas.read_csv(filepath_or_buffer="raw_logs.csv")

# Step 2: One-hot feature encoding transformation with implicit integer casting (Lesson 10)
processed_df = pandas.get_dummies(source_df, columns=["user_status"], dtype=int)

# Step 3: Precise memory allocation diagnostics audit (Lesson 5)
print(processed_df.memory_usage(deep=True))

7. Кастомная импутация пропусков NaN через .apply() на основе медианы ​

Задача: Прочитайте файл "sensor_inputs.parquet" (Урок 8). В нем содержится столбец "amplitude" с пропущенными значениями NaN (Урок 9). Рассчитайте медиану по этому столбцу методом .median() (Урок 5). Используя метод .apply(), напишите кастомную лямбда-функцию, которая проверяет каждый элемент через pandas.isna(x) и, если значение пропущено, подставляет туда вычисленную медиану (Урок 10). Выведите очищенный DataFrame.

Посмотреть решение
python
import pandas

# Step 1: Load parquet binary stream from disk (Lesson 8)
signals_df = pandas.read_parquet(path="sensor_inputs.parquet")

# Step 2: Calculate target statistical median constant (Lesson 5)
amplitude_median = signals_df["amplitude"].median()

# Step 3: Run custom cell-wise imputation replacement using lambda and apply (Lesson 9 & Lesson 10)
signals_df["amplitude"] = signals_df["amplitude"].apply(
    lambda x: amplitude_median if pandas.isna(x) else x
)
print(signals_df)

8. Выделение матрицы X и кодирование категорий после очистки дубликатов ​

Задача: Дан сырой датасет со строками-дубликатами: df_raw = pandas.DataFrame({"status": ["active", "error", "active", "active"], "target": [1, 0, 1, 1]}) (Урок 5). Удалите идентичные строки-повторения объектов на месте через .drop_duplicates(inplace=True) (Урок 9). Отделите матрицу признаков X, убрав столбец ответов "target" через метод .drop(axis=1) (Урок 7). К оставшейся матрице X примените One-Hot Encoding для колонки "status" (Урок 10). Выведите итоговую закодированную матрицу X.

Посмотреть решение
python
import pandas

df_raw = pandas.DataFrame({"status": ["active", "error", "active", "active"], "target": [1, 0, 1, 1]})

# Step 1: Purge identical rows duplicate patterns (Lesson 9)
df_raw.drop_duplicates(inplace=True)

# Step 2: Extract training feature tracking workspace X (Lesson 5 & Lesson 7)
matrix_X = df_raw.drop("target", axis=1)

# Step 3: Apply categorical binarization pipeline (Lesson 10)
final_encoded_X = pandas.get_dummies(matrix_X, columns=["status"], dtype=int)
print(final_encoded_X)

9. Кастомное поэлементное логарифмирование фичей через .apply() и NumPy ufuncs ​

Задача: Инициализируйте таблицу вещественных признаков df_features = pandas.DataFrame({"signal_strength": [1.5, 10.0, 100.0]}) (Урок 5). С помощью метода .apply() напишите лямбда-преобразование, которое вызывает внутри себя универсальную функцию вычисления натурального логарифма numpy.log() из модуля NumPy (Урок 8 модуля NumPy / Урок 10 модуля Pandas). Результат сохраните в новый столбец "log_strength" (Урок 7). Выведите таблицу.

Посмотреть решение
python
import numpy
import pandas

df_features = pandas.DataFrame({"signal_strength": [1.5, 10.0, 100.0]})

# Routing individual series scalar entries directly into low-level array ufuncs (NumPy Lesson 8 & Pandas Lesson 7, 10)
df_features["log_strength"] = df_features["signal_strength"].apply(lambda val: numpy.log(val))
print(df_features)

10. Поиск объектов по сложному побитовому условию над расчетными столбцами .apply() ​

Задача: Дан DataFrame текстовых логов df_nlp = pandas.DataFrame({"raw_text": ["Warning: Out of memory", "Success query", "Critical error: GIL block"]}) (Урок 5). С помощью метода .apply() посчитайте длину каждого текста в символах и запишите в столбец "char_count" (Урок 10). С помощью оператора .loc[] и побитового оператора & отфильтруйте строки таблицы, оставив только те записи, у которых "char_count" строго больше 15 и одновременно исходный текст "raw_text" содержит внутри себя подстроку "memory" (используйте синтаксис "memory" in text внутри лямбды для создания второй булевой маски) (Урок 6). Выведите отфильтрованные строки.

Посмотреть решение
python
import pandas

df_nlp = pandas.DataFrame({"raw_text": ["Warning: Out of memory", "Success query", "Critical error: GIL block"]})

# Step 1: Engineering a calculated sequence numeric column (Lesson 10)
df_nlp["char_count"] = df_nlp["raw_text"].apply(lambda text: len(text))

# Step 2: Constructing multi-conditional bitwise filter vectors arrays (Lesson 6 & Lesson 10)
# Condition A: Character count check
# Condition B: Substring containment check evaluated column-wise via apply
long_text_mask = df_nlp["char_count"] > 15
memory_keyword_mask = df_nlp["raw_text"].apply(lambda text: "memory" in text)

# Step 3: Extract subset sample blocks
filtered_nlp_batch = df_nlp.loc[long_text_mask & memory_keyword_mask, :]
print(filtered_nlp_batch)