Skip to content

6. Индексация в DataFrame: loc, iloc и булево маскирование ​

Выборка данных через .loc и .iloc ​

Строгие правила двумерной адресации в таблицах pandas ​

Для извлечения конкретных подмножеств данных из двумерного объекта pandas.DataFrame стандартный синтаксис квадратных скобок вроде df[row][col] считается плохой практикой. Он заставляет Pandas выполнять последовательный поиск в памяти (Chained Indexing), что сильно замедляет работу и приводит к скрытым багам: при попытке обновить данные через такой промежуточный срез интерпретатор выдаст предупреждение SettingWithCopyWarning, потому что запись попала во временную копию, а не в исходную таблицу.

Промышленным стандартом для точной двумерной адресации на C-скорости являются два специализированных индексных оператора: .loc[] и .iloc[]. Обращение к ним строится по единому геометрическому контракту, где параметры строк и столбцов перечисляются строго через запятую: dataframe.indexer[row_bounds, column_bounds]

Оператор .loc (Индексация по меткам) ​

Индексный оператор dataframe.loc[] предназначен для работы исключительно с явными текстовыми или числовыми метками (labels) строк и колонок.

  • Если вы делаете срез столбцов через .loc[:, "feature_A":"feature_C"], Pandas применит правила меткового слайсинга и включит правую границу "feature_C" в результат.

Оператор .iloc (Позиционная числовая индексация) ​

Индексный оператор dataframe.iloc[] работает как зеркальное отражение низкоуровневой индексации NumPy. Он полностью игнорирует текстовые имена колонок и меток, принимая на вход строго порядковые целые числа (integer positions), начиная с 0.

  • При позиционном слайсинге через .iloc[:, 0:2] действуют стандартные правила Python — правая граница никогда не включается в результат (столбец с индексом 2 будет отброшен).
python
import pandas

# Simulating a small dataset with custom explicit string row indices
raw_data_dict = {"feature_A": [1.0, 2.0, 3.0], "feature_B": [0.1, 0.2, 0.3]}
df = pandas.DataFrame(data=raw_data_dict, index=["sample_X", "sample_Y", "sample_Z"])

# Scenario 1: Exact label targeting using .loc
scalar_label = df.loc["sample_Y", "feature_B"]  # Outputs: 0.2

# Scenario 2: Exact integer position targeting using .iloc
scalar_pos = df.iloc[1, 1]                      # Outputs: 0.2

Булева фильтрация строк датасета ​

Векторизованный отбор объектов по условиям фичей ​

В ИИ-инженерии булево маскирование применяется непрерывно для очистки выборки от выбросов, выделения целевых классов или нарезки специфических батчей данных. Когда вы применяете оператор сравнения к отдельному столбцу таблицы, Pandas возвращает одномерную булеву маску типа bool. Передавая эту маску в первую координату (координату строк) оператора .loc[], вы мгновенно отфильтровываете датасет.

python
import pandas

raw_logs = {"age": [25, 45, 31, 28], "score": [0.9, 0.4, 0.95, 0.2]}
df_logs = pandas.DataFrame(raw_logs)

# Step 1: Generate vector boolean condition mask
young_users_mask = df_logs["age"] < 30

# Step 2: Extract matching rows directly on C-velocity speed
filtered_dataset = df_logs.loc[young_users_mask, :]

Сложное комбинирование условий побитовыми операторами ​

Если строки необходимо отфильтровать по цепочке из нескольких признаков, стандартные логические союзы Python and/or использовать запрещено. Вместо них применяются векторизованные побитовые операторы:

  • & — логическое И (AND)
  • | — логическое ИЛИ (OR)
  • ~ — логическое НЕ / инверсия (NOT)

Изоляция условий круглыми скобками

При построении сложных булевых фильтров в Pandas каждое изолированное логическое условие обязательно должно быть обернуто в круглые скобки. Побитовые операторы имеют наивысший приоритет исполнения в Python, и без скобок интерпретатор выдаст критическую ошибку ValueError.

python
import pandas

raw_logs = {"age": [25, 45, 31, 28], "score": [0.9, 0.4, 0.95, 0.2]}
df_logs = pandas.DataFrame(raw_logs)

# Correct industry syntax using explicit parenthesis and bitwise AND
target_batch = df_logs.loc[(df_logs["age"] >= 20) & (df_logs["score"] > 0.5), :]

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

1. Явная выборка признака через .loc ​

Задача: Дан DataFrame df = pandas.DataFrame({"loss": [0.5, 0.2], "accuracy": [0.7, 0.9]}, index=["run_A", "run_B"]). С помощью оператора .loc[] извлеките значение "accuracy" для эксперимента "run_B". Выведите результат.

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

df = pandas.DataFrame({"loss": [0.5, 0.2], "accuracy": [0.7, 0.9]}, index=["run_A", "run_B"])

# Extracting specific cell via explicit string coordinates labels
target_metric = df.loc["run_B", "accuracy"]
print(target_metric)  # Outputs: 0.9

2. Позиционное извлечение подматрицы через .iloc ​

Задача: Создайте таблицу размером 3x3, заполнив её числами от 1 до 9 через pandas.DataFrame(data=[[1,2,3],[4,5,6],[7,8,9]]). С помощью позиционного оператора .iloc[] извлеките подматрицу, содержащую первые две строки и первые два столбца. Выведите результат.

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

matrix_df = pandas.DataFrame(data=[[1,2,3],[4,5,6],[7,8,9]])

# Positional slicing excludes the stop bound argument (0:2 means indices 0, 1)
sub_matrix = matrix_df.iloc[0:2, 0:2]
print(sub_matrix)

3. Базовая булева фильтрация по порогу ​

Задача: Дан датасет df_scores = pandas.DataFrame({"confidence": [0.15, 0.88, 0.42, 0.95, 0.61]}). Напишите строку кода с использованием оператора .loc[], которая отбирает только те строки, у которых значение столбца "confidence" строго больше 0.5. Выведите отфильтрованную таблицу.

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

df_scores = pandas.DataFrame({"confidence": [0.15, 0.88, 0.42, 0.95, 0.61]})

# Filtering rows via a vector boolean mask profile condition
high_confidence_samples = df_scores.loc[df_scores["confidence"] > 0.5, :]
print(high_confidence_samples)

4. Комплексный отбор объектов по двум фичам ​

Задача: Создайте таблицу df_signals = pandas.DataFrame({"amplitude": [5.0, 12.5, 8.0, 15.2], "status": ["valid", "error", "valid", "valid"]}). Используя побитовый оператор & и обязательные круглые скобки, отфильтруйте датасет, оставив только строки, где "amplitude" больше 10 и одновременно "status" равен строго "valid". Выведите результат.

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

df_signals = pandas.DataFrame({"amplitude": [5.0, 12.5, 8.0, 15.2], "status": ["valid", "error", "valid", "valid"]})

# Combining two series constraints requiring explicit parenthesis syntax
clean_signals = df_signals.loc[(df_signals["amplitude"] > 10) & (df_signals["status"] == "valid"), :]
print(clean_signals)

5. Инвертирование булевой маски через тильду ​

Задача: На основе объекта df_signals из прошлого упражнения напишите булево условие поиска ошибочных строк df_signals["status"] == "error". Примените к этой маске оператор побитового отрицания ~ (NOT) внутри .loc[], чтобы получить инвертированный датасет, не содержащий ошибок. Выведите результат.

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

df_signals = pandas.DataFrame({"amplitude": [5.0, 12.5, 8.0, 15.2], "status": ["valid", "error", "valid", "valid"]})

# Using tilde operator to invert boolean criteria flags vector
non_error_signals = df_signals.loc[~(df_signals["status"] == "error"), :]
print(non_error_signals)

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

6. Булево маскирование с расчетом статистик describe ​

Задача: Создайте двумерную таблицу experimental_dataset = pandas.DataFrame({"loss_rate": [0.95, 0.12, 0.04, 0.44, 0.01], "layer_id": [1, 2, 2, 1, 2]}) (Урок 5). С помощью оператора .loc[] отфильтруйте строки датасета, оставив только те объекты, у которых "layer_id" равен строго 2 (Урок 6). К полученной отфильтрованной подматрице примените метод генерации базовых статистик .describe() (Урок 5). Выведите результат.

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

experimental_dataset = pandas.DataFrame({"loss_rate": [0.95, 0.12, 0.04, 0.44, 0.01], "layer_id": [1, 2, 2, 1, 2]})

# Step 1: Filter row samples belonging to the second hidden layer (Lesson 6)
layer_two_submatrix = experimental_dataset.loc[experimental_dataset["layer_id"] == 2, :]

# Step 2: Compute statistical aggregation insights summary (Lesson 5)
layer_two_summary = layer_two_submatrix.describe()
print(layer_two_summary)

7. Слайсинг текстовых колонок после сортировки индексов таблицы ​

Задача: Дана неотфильтрованная таблица фичей: raw_df = pandas.DataFrame({"feature_B": [0.5, 0.9], "feature_A": [10, 20]}, index=["sample_Z", "sample_X"]) (Урок 5). Выполните сортировку строк по индексным меткам на месте (Урок 4). После этого с помощью оператора .loc[] извлеките срез строк от "sample_X" до "sample_Z" и срез столбцов от "feature_A" до "feature_B" (Урок 6). Объясните, почему при метковом слайсинге обе правые границы попали в итоговый массив (Урок 3).

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

raw_df = pandas.DataFrame({"feature_B": [0.5, 0.9], "feature_A": [10, 20]}, index=["sample_Z", "sample_X"])

# Aligning index structures alphabetically in-place (Lesson 4)
raw_df.sort_index(inplace=True)  # Order becomes: sample_X, sample_Z

# Extracting a 2D bounding slice via labels (Lesson 3 & Lesson 6)
# Explicit string slice bounds are fully inclusive in pandas framework contracts
targeted_sub_df = raw_df.loc["sample_X":"sample_Z", "feature_A":"feature_B"]
print(targeted_sub_df)

8. Фильтрация строк DataFrame на базе квантованного числового диапазона NumPy ​

Задача: Сгенерируйте упорядоченный вектор из 6 элементов через numpy.arange(6), принудительно выставив тип numpy.int8 (Урок 4 модуля NumPy). Оберните этот массив в столбец таблицы pandas.DataFrame({"token_index": quantized_vector}) (Урок 5). Используя комбинированное побитовое условие внутри .loc[], извлеките строки, у которых значения "token_index" находятся строго в диапазоне от 2 до 4 включительно (Урок 6). Выведите итоговый подмассив.

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

# Generating memory-optimized arrays buffer (NumPy Lesson 4)
quantized_vector = numpy.arange(6, dtype=numpy.int8)

# Framing container matrix layers (Pandas Lesson 5)
tokens_df = pandas.DataFrame({"token_index": quantized_vector})

# Extracting subset rows following closed range criteria (Pandas Lesson 6)
target_tokens_batch = tokens_df.loc[(tokens_df["token_index"] >= 2) & (tokens_df["token_index"] <= 4), :]
print(target_tokens_batch)

9. Позиционный iloc-слайсинг матрицы, созданной из линейной сетки ​

Задача: Сгенерируйте линейную числовую последовательность из 12 элементов от 1.5 до 7.0 через numpy.linspace() (Урок 3 модуля NumPy). Превратите полученный вектор в двумерную матрицу NumPy размерностью (4, 3) с помощью метода .reshape() (Урок 18 модуля NumPy). Оберните эту матрицу в pandas.DataFrame (Урок 5). Используя высокоскоростной позиционный оператор .iloc[], извлеките подматрицу из средних двух строк (индексы 1 и 2) и последних двух столбцов (индексы 1 и 2) (Урок 6). Выведите срез.

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

# Multi-dimensional arrays transformation pipeline layout (NumPy Lessons 3 & 18)
linear_matrix = numpy.linspace(1.5, 7.0, 12).reshape(4, 3)

# Wrapping raw array references into pandas (Pandas Lesson 5)
dataset_df = pandas.DataFrame(linear_matrix)

# Extracting inner sub-matrix using integer slicing boundaries (Pandas Lesson 6)
# Remember: integer bounds are exclusive (1:3 means rows/cols at positions 1 and 2)
extracted_sub_matrix = dataset_df.iloc[1:3, 1:3]
print(extracted_sub_matrix)

10. Комплексная булева фильтрация с поиском зашумленных NaN-меток ​

Задача: Дан DataFrame логов экспериментов нейросети: logs_df = pandas.DataFrame({"accuracy": [0.55, numpy.nan, 0.92, 0.44], "status": ["active", "corrupted", "active", "active"]}) (Урок 4 / Урок 5). Напишите сложное булево условие с использованием функции numpy.isnan() (Урок 8 модуля NumPy): отберите только те строки, у которых значение "accuracy" НЕ является NaN (используйте оператор побитового отрицания ~), и при этом "status" равен строго "active" (Урок 6). Выведите чистый батч строк.

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

logs_df = pandas.DataFrame({"accuracy": [0.55, numpy.nan, 0.92, 0.44], "status": ["active", "corrupted", "active", "active"]})

# Creating a complex logical condition mask screening for missing floats and strings flags (NumPy Lesson 8 & Pandas Lesson 6)
valid_active_mask = (~numpy.isnan(logs_df["accuracy"])) & (logs_df["status"] == "active")

# Extracting sanitized records batch
clean_logs_batch = logs_df.loc[valid_active_mask, :]
print(clean_logs_batch)