Skip to content

11. Агрегация данных, группировка (groupby) и конвертация в тензоры NumPy ​

Группировка и расчет кумулятивных статистик ​

Концепция Split-Apply-Combine при группировке данных ​

В процессах разведочного анализа (EDA) и анализа распределения признаков ИИ-инженеру часто требуется рассчитать статистики не по всему датасету целиком, а в разрезе конкретных категорий или классов (например, узнать средний чек пользователей систем iOS и Android раздельно). Для этого применяется мощный механизм dataframe.groupby(by), работающий по концепции Split-Apply-Combine (Разбить-Применить-Объединить):

  1. Split: Таблица разбивается на изолированные группы по уникальным значениям выбранного категориального столбца by.
  2. Apply: К числовым столбцам каждой группы применяется агрегирующий ufunc-метод (.mean(), .sum(), .std(), .max()).
  3. Combine: Результаты расчетов объединяются обратно в наглядную сводную таблицу.
python
import pandas

raw_metrics = {
    "class_label": [0, 1, 0, 1],
    "feature_loss": [0.85, 0.12, 0.65, 0.08]
}
df_metrics = pandas.DataFrame(raw_metrics)

# Grouping by categorical targets to evaluate average loss values per class
grouped_summary = df_metrics.groupby(by="class_label").mean()

print(grouped_summary)
# Outputs aggregated summary table:
#              feature_loss
# class_label              
# 0                    0.75
# 1                    0.10

Отбор одной колонки после группировки ​

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

python
# Aggregating a single pre-selected column instead of the whole table
single_column_means = df_metrics.groupby(by="class_label")["feature_loss"].mean()
print(single_column_means)
# Outputs:
# class_label
# 0    0.75
# 1    0.10
# Name: feature_loss, dtype: float64

Экспорт данных в тензорные пайплайны ​

Мост между Pandas и глубоким обучением ​

Объект pandas.DataFrame — это великолепная абстракция верхнего уровня для очистки, фильтрации, кодирования текста и проектирования фичей силами процессора (CPU). Однако современные фреймворки глубокого обучения, такие как PyTorch или TensorFlow, не умеют работать с таблицами Pandas напрямую. На вход нейросетевым слоям и загрузчикам данных (DataLoaders) необходимо передавать чистые, низкоуровневые, строго однородные многомерные тензоры.

Бесшовная конвертация через .to_numpy() ​

Финальным шагом любого пайплайна предобработки в Pandas является выгрузка очищенной матрицы признаков во внешний математический буфер памяти. Для этого к очищенной таблице или Series применяется встроенный метод .to_numpy() (или его старый псевдоним-атрибут .values).

Этот метод мгновенно сбрасывает все текстовые обертки, названия столбцов, индексные сетки строк и возвращает чистый, оптимизированный, непрерывный массив numpy.ndarray. Этот массив полностью готов к упаковке в тензоры и отправке на аппаратные ядра GPU/TPU ускорителей.

python
import pandas

clean_features = {"x1": [1.5, 3.0], "x2": [0.5, 2.5]}
df_clean = pandas.DataFrame(clean_features)

# Exporting index-aware pandas table into raw low-level math_oge array buffer
numpy_training_matrix = df_clean.to_numpy()

print(type(numpy_training_matrix))  # Outputs strictly: <class 'numpy.ndarray'>
print(numpy_training_matrix.shape)   # Outputs shape geometry: (2, 2)

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

1. Вычисление группового среднего значения ​

Задача: Дан DataFrame df_samples = pandas.DataFrame({"category": ["A", "B", "A", "B"], "value": [10, 20, 30, 40]}). Сгруппируйте данные по столбцу "category" с помощью .groupby() и вычислите среднее значение числового поля для каждой группы. Выведите результат.

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

df_samples = pandas.DataFrame({"category": ["A", "B", "A", "B"], "value": [10, 20, 30, 40]})

# Grouping by string labels to compute segment means
group_means = df_samples.groupby(by="category").mean()
print(group_means)

2. Экспорт DataFrame в сырую матрицу NumPy ​

Задача: Создайте таблицу признаков df_inputs = pandas.DataFrame({"f1": [0.5, 0.9], "f2": [1.2, 3.4]}). С помощью метода .to_numpy() конвертируйте её в низкоуровневый массив, сохранив результат в переменную X_array. Выведите тип полученной структуры через type().

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

df_inputs = pandas.DataFrame({"f1": [0.5, 0.9], "f2": [1.2, 3.4]})

# Dumping high-level table structure into an unindexed array buffer
X_array = df_inputs.to_numpy()
print("Object classification type:", type(X_array))  # <class 'numpy.ndarray'>

3. Экспорт одномерного Series в вектор NumPy ​

Задача: Создайте одномерный объект target_series = pandas.Series([1, 0, 1, 0], name="labels"). Выгрузите его элементы в чистый вектор NumPy с помощью свойства .values. Выведите полученный объект.

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

target_series = pandas.Series([1, 0, 1, 0], name="labels")

# Extracting raw internal C-buffer vector
y_vector = target_series.values
print(y_vector)
print("Underlying type classification:", type(y_vector))

4. Подсчет максимальных сигналов по группам ​

Задача: Дан датасет логов датчиков df_sensors = pandas.DataFrame({"device": ["dev_1", "dev_2", "dev_1"], "amplitude": [12.5, 45.1, 14.8]}). Сгруппируйте строки по столбцу "device" и найдите максимальное значение амплитуды (.max()) для каждого прибора. Выведите сводную таблицу.

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

df_sensors = pandas.DataFrame({"device": ["dev_1", "dev_2", "dev_1"], "amplitude": [12.5, 45.1, 14.8]})

# Finding extreme peaks for each isolated device cluster
device_maxima = df_sensors.groupby(by="device").max()
print(device_maxima)

5. Суммирование метрик по целевым классам ​

Задача: Создайте DataFrame df_losses = pandas.DataFrame({"target": [0, 1, 0, 1], "loss_weight": [0.45, 0.12, 0.88, 0.02]}). Сгруппируйте данные по колонке "target" и вычислите суммарный вес потерь (.sum()) для каждого класса. Выведите результат.

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

df_losses = pandas.DataFrame({"target": [0, 1, 0, 1], "loss_weight": [0.45, 0.12, 0.88, 0.02]})

# Accumulating metrics subsets based on integer class groupings
total_class_losses = df_losses.groupby(by="target").sum()
print(total_class_losses)

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

6. Чтение Parquet-файла, группировка по классам и экспорт статистик ​

Задача: Загрузите бинарный колоночный файл данных "model_evaluation.parquet" (Урок 8). Сгруппируйте полученную таблицу по категориальному столбцу меток "class_id" (Урок 11). Рассчитайте среднее значение и стандартное отклонение для всех числовых фичей батча (Урок 11 / Урок 15). Выведите итоговые сводные метрики на экран.

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

# Step 1: Loading high-speed data stream from disk (Lesson 8)
evaluation_df = pandas.read_parquet(path="model_evaluation.parquet")

# Step 2: Running multi-conditional group aggregation pipeline (Lesson 11)
grouped_means = evaluation_df.groupby(by="class_id").mean()
grouped_stds = evaluation_df.groupby(by="class_id").std()

print("Grouped Features Means:\n", grouped_means)
print("Grouped Features Deviations:\n", grouped_stds)

7. Feature Engineering текстовых строк с группировкой по длине последовательности ​

Задача: Дан DataFrame сырых логов текстовых эмбеддингов df_nlp = pandas.DataFrame({"raw_text": ["short", "very long text sequence", "tiny", "extended sentence string"], "label": [1, 0, 1, 0]}) (Урок 5). С помощью метода .apply() посчитайте количество слов в каждой строке и запишите результат в новую расчетную колонку "word_count" (Урок 10 / Урок 7). Сгруппируйте таблицу по новому признаку "word_count" и найдите среднее значение целевого класса "label" для каждой группы (Урок 11). Выведите сводную таблицу.

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

df_nlp = pandas.DataFrame({"raw_text": ["short", "very long text sequence", "tiny", "extended sentence string"], "label": [1, 0, 1, 0]})

# Step 1: Feature Engineering calculated column tracking word length tokens (Lesson 7 & Lesson 10)
df_nlp["word_count"] = df_nlp["raw_text"].apply(lambda text: len(text.split()))

# Step 2: Evaluate label interactions grouped by text volume lengths (Lesson 11)
word_count_summary = df_nlp.groupby(by="word_count")["label"].mean()
print(word_count_summary)

8. Очистка датасета от дубликатов, пропусков и экспорт матрицы X в NumPy ​

Задача: Загрузите тяжелый лог обучения "raw_data.csv" (Урок 8). Выполните операцию принудительного удаления идентичных строк-дубликатов на месте (Урок 9). Посчитайте количество оставшихся скрытых пустот через .isna().sum(), и заполните все обнаруженные пропуски константой 0.0 на месте (Урок 9). Отделите матрицу фичей X, убрав столбец таргета "label" по оси axis=1 (Урок 7). Сбросьте высокоуровневые абстракции Pandas и экспортируйте полученную чистую матрицу X в сырой низкоуровневый массив numpy.ndarray через метод .to_numpy() (Урок 11). Выведите форму .shape полученного массива (Урок 2 модуля NumPy).

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

# Step 1: Disk ingestion data loading (Lesson 8)
raw_df = pandas.read_csv(filepath_or_buffer="raw_data.csv")

# Step 2: Rigorous sorting and memory sanitization pipeline (Lesson 9)
raw_df.drop_duplicates(inplace=True)
raw_df.fillna(0.0, inplace=True)

# Step 3: Feature separation dropping layout blocks (Lesson 7)
X_features_df = raw_df.drop("label", axis=1)

# Step 4: Exporting clear array reference to low-level hardware memory tracks (Lesson 11)
X_numpy_matrix = X_features_df.to_numpy()

print("Final array structure type classification:", type(X_numpy_matrix))
print("Final NumPy matrix dimensions shape geometry:", X_numpy_matrix.shape)  # NumPy Lesson 2

9. Булево фильтрование батча с последующей выгрузкой в ufuncs-математику NumPy ​

Задача: Дан DataFrame вероятностей предсказаний df_probs = pandas.DataFrame({"probability": [0.88, 0.12, 0.45, 0.99, 0.03], "status": ["active", "active", "corrupted", "active", "corrupted"]}) (Урок 5). С помощью оператора .loc[] отфильтруйте таблицу, оставив только строки со статусом "active" (Урок 6). Извлеките столбец "probability" для отфильтрованных строк, переведите его в вектор NumPy с помощью свойства .values (Урок 11) и пропустите через векторизованную ufunc-функцию расчета логарифмического штрафа -numpy.log() из модуля NumPy (Урок 8 модуля NumPy). Выведите массив штрафов.

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

df_probs = pandas.DataFrame({"probability": [0.88, 0.12, 0.45, 0.99, 0.03], "status": ["active", "active", "corrupted", "active", "corrupted"]})

# Step 1: Filter row samples according to categorical status constraints (Lesson 6)
active_samples_df = df_probs.loc[df_probs["status"] == "active", :]

# Step 2: Unload column entries buffer to raw array storage tracks (Lesson 11)
probabilities_array = active_samples_df["probability"].values

# Step 3: Stream NumPy mathematical universal functions on C-level (NumPy Lesson 8)
log_penalties_vector = -numpy.log(probabilities_array)
print("Calculated errors vector output:", log_penalties_vector)

10. Комплексный пайплайн: One-Hot кодирование, групповая агрегация и экспорт ​

Задача: Дан сырой датасет объектов: df_raw = pandas.DataFrame({"device": ["ios", "android", "ios", "android"], "loss": [0.12, 0.45, 0.08, 0.99]}) (Урок 5). Примените алгоритм One-Hot Encoding для перевода категорий столбца "device" в бинарные числовые столбцы с принудительным выставлением типа dtype=int (Урок 10). Сгруппируйте полученную закодированную таблицу по новому столбцу "device_ios" (Урок 11). Рассчитайте максимальное значение признака "loss" для каждой группы объектов (Урок 11 / Урок 15). Из полученной сводной таблицы выгрузите элементы буфера в чистую матрицу NumPy с помощью метода .to_numpy() (Урок 11). Выведите итоговую матрицу на экран.

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

df_raw = pandas.DataFrame({"device": ["ios", "android", "ios", "android"], "loss": [0.12, 0.45, 0.08, 0.99]})

# Step 1: Feature Engineering categorical binarization pipeline (Lesson 10)
encoded_dataset_df = pandas.get_dummies(df_raw, columns=["device"], dtype=int)

# Step 2: Running group aggregation tracking peak metrics per layer (Lesson 11 & Lesson 15)
grouped_maxima_df = encoded_dataset_df.groupby(by="device_ios").max()

# Step 3: Exporting dataframe abstraction layers into unindexed matrix array buffer (Lesson 11)
final_numpy_matrix = grouped_maxima_df.to_numpy()

print("Final exported low-level array outputs:\n", final_numpy_matrix)