Одной из тех надоедливых вещей, которые мы все пытаемся понять, когда изучаем Pandas, является различие между .loc
и .iloc
.
Давайте покончим с этим недопониманием и проясним разницу между этими двумя методами. Я приведу много примеров, и надеюсь, что различие будет намного яснее к концу этого блога.
Что такое .loc и .iloc в Pandas?
И .loc
, и .iloc
являются важными атрибутами DataFrame в Pandas, и оба используются для выбора конкретных подмножеств данных. Их цель состоит в том, чтобы получать доступ и позволять манипулировать определенной частью DataFrame вместо всего DataFrame.
Особенность |
.loc |
.iloc |
Синтаксис |
df.loc[индекс_строки, индекс_столбца] |
df.iloc[индекс_строки, индекс_столбца] |
Метод индексации |
Индексация на основе меток |
Индексация на основе позиции |
Используется для ссылки |
Метки строк и столбцов |
Числовые индексы строк и столбцов (начиная с 0) |
Как мы можем видеть из таблицы, синтаксис выглядит очень похожим. Разница заключается в том, как мы используем аргументы row_indexer
и column_indexer
. Это потому, что два метода предлагают разные подходы к индексации данных: в то время как .loc
индексирует на основе меток, .iloc
принимает числовой индекс позиции строк и столбцов в качестве аргументов.
Давайте рассмотрим каждый из этих двух методов более подробно, начиная с .loc
.
Используя .loc: Выбор по меткам
Для наглядности рассмотрим гипотетическую базу данных клиентов, представленную этим DataFrame, называемым df
, где Customer ID
представляет собой индекс строки:
Customer ID |
Name |
Country |
Region |
Age |
C123 |
John Doe |
United States |
North America |
67 |
C234 |
Petra Müller |
Germany |
Europe |
51 |
C345 |
Али Хан |
Пакистан |
Азия |
19 |
C456 |
Мария Гонзалес |
Мексика |
Северная Америка |
26 |
C567 |
Дэвид Ли |
Китай |
Азия |
40 |
Есть четыре основных способа выбора строк с помощью .loc
. Они включают:
- Выбор одной строки
- Выбор нескольких строк
- Выбор среза строк
- Условный выбор строк
Выбор одной строки с использованием .loc
Для выбора одной строки мы используем метку строки, которую хотим получить, как row_indexer
. Соответственно, синтаксис выглядит так: df.loc['метка_строки']
. Давайте воспользуемся этим, чтобы отобразить всю информацию о нашем клиенте Али Хане:
df.loc['C345']
C345 |
|
Имя |
Али Хан |
Страна |
Пакистан |
Регион |
Азия |
Возраст |
19 |
Выбор нескольких строк с использованием .loc
Если мы хотим выбрать несколько строк, которые не обязательно следуют друг за другом, мы должны передать список их меток строк в качестве аргумента row_indexer
. Это означает, что нам нужно использовать не одну, а две пары квадратных скобок: одну для обычного синтаксиса .loc
и одну для списка меток.
Строка df.loc[['метка_строки_1', 'метка_строки_2']]
вернет две строки из DataFrame df
, указанные в списке. Допустим, мы хотим получить информацию не только о Али Хане, но и о Дэвиде Ли:
df.loc[['C345', 'C567']]
ID клиента |
Имя |
Страна |
Регион |
Возраст |
C345 |
Али Хан |
Пакистан |
Азия |
19 |
C567 |
Дэвид Ли |
Китай |
Азия |
40 |
Выбор диапазона строк с помощью .loc
Мы можем выбрать диапазон строк, передав метки первой и последней строк с двоеточием между ними: df.loc['row_label_start':'row_label_end']
. Мы можем отобразить первые четыре строки нашего DataFrame так:
df.loc['C123' : 'C456']
ID клиента |
Имя |
Страна |
Регион |
Дата регистрации |
C123 |
Джон Доу |
Соединенные Штаты |
Северная Америка |
67 |
C234 |
Петра Мюллер |
Германия |
Европа |
51 |
C345 |
Али Хан |
Пакистан |
Азия |
19 |
C456 |
Мария Гонсалес |
Мексика |
Северная Америка |
26 |
Есть две вещи, о которых следует помнить:
- Вывод включает строку, указанную в
row_label_end
. Это отличается от.iloc
, который мы рассмотрим позже. - Мы используем только одну пару квадратных скобок, даже если хотим получить несколько строк. Мы не используем список для указания различных строк, поэтому использование двух квадратных скобок приведет к ошибке
SyntaxError
.
Условный отбор строк с помощью .loc
Мы также можем возвращать строки на основе условного выражения. Мы можем фильтровать все строки в зависимости от того, выполняют ли они определенное условие, и отображать только те, которые соответствуют этому условию.
Соответствующий синтаксис: df.loc[conditional_expression]
, при этом conditional_expression
является выражением о допустимых значениях в конкретном столбце.
Для столбцов с ненумерическими данными (такими как Имя
или Страна
) оператором может быть использован только оператор равенства или неравенства, так как между значениями нет порядка. Мы можем, например, вернуть все строки клиентов, которые не из Азии:
df.loc[df['Region'] != 'Asia']
Идентификатор клиента |
Имя |
Страна |
Регион |
Возраст |
C123 |
Джон Доу |
Соединённые Штаты |
Северная Америка |
67 |
C234 |
Петра Мюллер |
Германия |
Европа |
51 |
C456 |
Мария Гонсалес |
Мексика |
Северная Америка |
26 |
Выбор одного столбца с использованием .loc
Для выбора столбцов нам необходимо указать аргумент column_indexer
, который следует после аргумента row_indexer
. Если мы хотим указать только column_indexer
, нам нужно somehow пометить, что мы хотим вернуть все строки и фильтровать только столбцы. Давайте посмотрим, как мы можем это сделать!
Выбор одного столбца можно выполнить, указав column_indexer
с меткой соответствующего столбца. Чтобы получить все строки, нам необходимо указать row_indexer
с простым двоеточием. Мы получаем синтаксис, который выглядит так: df.loc[:, 'column_name']
.
Давайте отобразим Имя
каждого клиента:
df.loc[:, 'Name']
Идентификатор клиента |
Имя |
C123 |
Джон Доу |
C234 |
Петра Мюллер |
C345 |
Али Хан |
C456 |
Мария Гонсалес |
C567 |
Дэвид Ли |
Выбор нескольких столбцов с помощью .loc
Аналогично выбору нескольких строк, нам необходимо передать список меток столбцов, если мы хотим вернуть несколько столбцов DataFrame, которые не обязательно следует друг за другом по порядку: df.loc[:, [col_label_1, 'col_label_2']]
.
Предположим, что мы хотели бы добавить возраст всех клиентов к нашему последнему выводу, это будет работать так:
df.loc[:, ['Name', 'Age']]
ID клиента |
Имя |
Возраст |
C123 |
Джон Доу |
67 |
C234 |
Петра Мюллер |
51 |
C345 |
Али Хан |
19 |
C456 |
Мария Гонсалес |
26 |
C567 |
Давид Ли |
40 |
Выбор диапазона столбцов с помощью .loc
Использование двоеточия между метками двух столбцов выберет все столбцы в диапазоне между двумя указанными столбцами. Включает конечный столбец, что означает, что столбец с именем col_end
также будет выбран в стандартном синтаксисе, который выглядит следующим образом: df.loc[:, 'col_start':'col_end']
.
Если нас интересовали Имя
, Страна
и Регион
наших клиентов, наша строка кода могла бы выглядеть так:
df.loc[:, 'Name':'Region']
Идентификатор клиента |
Имя |
Страна |
Регион |
C123 |
Джон Доу |
Соединенные Штаты |
Северная Америка |
C234 |
Петра Мюллер |
Германия |
Европа |
C345 |
Али Кхан |
Пакистан |
Азия |
C456 |
Мария Гонсалес |
Мексика |
Северная Америка |
C567 |
Дэвид Ли |
Китай |
Азия |
Комбинированный выбор строк и столбцов с использованием .loc
Также возможно указать как row_indexer
, так и column_indexer
. Это можно использовать для извлечения одного фрагмента информации, то есть одной ячейки из DataFrame. Для этого мы указываем одну строку и один столбец, используя синтаксис df.loc['row_label', 'column_name']
.
Более полезный случай – вернуть под-DataFrame, который сосредотачивается именно на тех строках и столбцах, которые нас интересуют. Можно указать оба индексатора в виде списков, используя квадратные скобки, или в виде среза, используя двоеточие, и даже комбинировать это с условным выражением для выбора строк.
Вот один пример возврата Name
, Country
и Region
каждого клиента с Age
более 30:
df.loc[df['Age'] > 30, 'Name':'Region']
ID клиента |
Имя |
Страна |
Регион |
C123 |
Джон Доу |
Соединенные Штаты |
Северная Америка |
C234 |
Петра Мюллер |
Германия |
Европа |
C567 |
Дэвид Ли |
Китай |
Азия |
Использование .iloc: выбор по целочисленной позиции
.iloc
выбирает по позиции, а не по метке. Это стандартный синтаксис использования .iloc
: df.iloc[row_indexer, column_indexer]
. Есть две особенности, на которые стоит обратить внимание:
- Счет с 0: первая строка и столбец имеют индекс 0, вторая – индекс 1 и так далее.
- Исключительность конечного значения диапазона: при использовании среза строка или столбец, указанные после двоеточия, не включаются в выборку.
Выбор одной строки с использованием .iloc
Одну строку можно выбрать, используя целое число, представляющее номер индекса строки, в качестве row_indexer
. Нам не нужны кавычки, поскольку мы вводим целое число, а не строку метки, как это делали с .loc
. Чтобы вернуть первую строку DataFrame с названием df
, введите df.iloc[0]
.
В нашем примере DataFrame эта строка кода возвращает информацию о Джоне Доу:
df.iloc[0]
C123 |
|
Имя |
Джон Доу |
Страна |
Соединенные Штаты |
Регион |
Северная Америка |
Возраст |
67 |
Выбор нескольких строк с помощью .iloc
Выбор нескольких строк работает в .iloc
, как и в .loc
— мы вводим целые числа индексов строк в списке в квадратных скобках. Синтаксис выглядит следующим образом: df.iloc[[0, 3, 4]]
.
Соответствующий вывод в нашей таблице клиентов можно увидеть ниже:
df.iloc[[0, 3, 4]]
ID клиента |
Имя |
Страна |
Регион |
Возраст |
C123 |
Джон Доу |
Соединенные Штаты |
Северная Америка |
67 |
C456 |
Мария Гонсалес |
Мексика |
Северная Америка |
26 |
C567 |
Дэвид Ли |
Китай |
Азия |
40 |
Выбор среза строк с использованием .iloc
Для выбора среза строк мы используем двоеточие между двумя указанными целыми числами индекса строки. Теперь нам нужно обратить внимание на исключительность, упомянутую ранее.
Мы можем взять строку df.iloc[1:4]
в качестве примера, чтобы проиллюстрировать эту концепцию. Номер индекса 1 означает вторую строку, поэтому наш срез начинается там. Целое число индекса 4 представляет собой пятую строку – но так как .iloc
не включает последний элемент для выбора среза, наш вывод будет включать все строки вплоть до последней перед этой. Таким образом, он вернет вторую, третью и четвертую строки.
Давайте докажем, что эта строка работает, как должна:
df.iloc[1:4]
Идентификатор клиента |
Имя |
Страна |
Регион |
Возраст |
C234 |
Петра Мюллер |
Германия |
Европа |
51 |
C345 |
Али Хан |
Пакистан |
Азия |
19 |
C456 |
Мария Гонсалес |
Мексика |
Северная Америка |
26 |
Выбор одного столбца с помощью .iloc
Логика выбора столбцов с использованием .iloc
соответствует тому, что мы узнали до сих пор. Давайте посмотрим, как это работает для отдельных столбцов, нескольких столбцов и срезов столбцов.
Как и с .loc
, важно указать row_indexer
перед тем, как мы сможем перейти к column_indexer
. Чтобы получить значения третьего столбца df
для каждой строки, мы вводим df.iloc[:, 2]
.
Поскольку Region
является третьим столбцом в нашем DataFrame, он будет извлечен в результате этой строки кода:
df.iloc[:, 2]
ID клиента |
Регион |
C123 |
Северная Америка |
C234 |
Европа |
C345 |
Азия |
C456 |
Северная Америка |
C567 |
Азия |
Выбор нескольких столбцов с использованием .iloc
Для выбора нескольких столбцов, которые не обязательно идут подряд, мы снова можем ввести список, содержащий целые числа в качестве column_indexer
. Строка df.iloc[:, [0, 3]]
возвращает как первый, так и четвертый столбцы.
В нашем случае отображается информация о Name
и Age
каждого клиента:
df.iloc[:, [0, 3]]
Customer ID |
Name |
Age |
C123 |
John Doe |
67 |
C234 |
Petra Müller |
51 |
C345 |
Ali Khan |
19 |
C456 |
Maria Gonzalez |
26 |
C567 |
David Lee |
40 |
Выбор среза столбцов с использованием .iloc
Для выбора срезов с использованием .iloc
логика column_indexer
соответствует логике row_indexer
. Столбец, представленный целым числом после двоеточия, не включается в результат. Чтобы получить второй и третий столбцы, строка кода должна выглядеть так: df.iloc[:, 1:3]
.
Эта строка ниже возвращает всю географическую информацию, которую мы имеем о наших клиентах:
df.iloc[:, 1:3]
ID клиента |
Страна |
Регион |
C123 |
Соединенные Штаты |
Северная Америка |
C234 |
Германия |
Европа |
C345 |
Пакистан |
Азия |
C456 |
Мексика |
Северная Америка |
C567 |
Китай |
Азия |
Объединение выбора строк и столбцов с помощью .iloc
Мы можем объединить то, что мы узнали о .iloc
, чтобы совместить выбор строк и столбцов. Снова возможно вернуть как одну ячейку, так и подмножество DataFrame. Чтобы вернуть единственную ячейку на пересечении строки 3 и столбца 4, мы вводим df.iloc[2, 3]
.
Как и с .loc
, мы можем указать оба индекса как списки, используя квадратные скобки, или как срез, используя двоеточие. Если мы хотим выбрать строки, используя условные выражения, это технически возможно и с .iloc
, но не рекомендуется. Использование имен меток и .loc
обычно гораздо более интуитивно и менее подвержено ошибкам.
Этот последний пример отображает Страна
, Регион
и Возраст
для первой, второй и пятой строки в нашем DataFrame:
df.iloc[[0,1,4], 1:4]
ID клиента |
Страна |
Регион |
Возраст |
C123 |
Соединенные Штаты |
Северная Америка |
67 |
C234 |
Германия |
Европа |
51 |
C567 |
Китай |
Азия |
40 |
.iloc против .loc: Когда использовать каждый из них
Обычно существует одно простое правило, когда выбор метода зависит от вашего знания DataFrame:
- Используйте
.loc
, когда вы знаете метки (названия) строк/столбцов. - Используйте
.iloc
когда вы знаете целочисленные позиции строк/столбцов.
Некоторые сценарии по своей природе предпочитают либо .loc
, либо .iloc
. Например, итерация по строкам или столбцам проще и интуитивнее с использованием целых чисел, чем с метками. Как мы уже упоминали, фильтрация строк на основе условий значений столбцов менее подвержена ошибкам при использовании имен меток столбцов.
Сценарии, предпочитающие .loc |
Сценарии, предпочитающие .iloc |
Ваш DataFrame имеет значимые имена индексов/столбцов. |
Вы итерируете по строкам/столбцам по их позиции. |
Вам нужно фильтровать на основе условий значений столбцов. |
Имена индексов/столбцов не имеют отношения к вашей задаче. |
KeyError, NameError и IndexError с .loc и .iloc
Давайте рассмотрим возможные проблемы. Частая ошибка при использовании .loc
– это возникновение KeyError
. Эта ошибка возникает, когда мы пытаемся получить доступ к метке строки или столбца, которая не существует в нашем DataFrame. Чтобы избежать этого, нам всегда нужно убедиться, что используемые метки точны и соответствуют существующим меткам в вашем DataFrame, а также дважды проверить на наличие опечаток.
Кроме того, важно всегда использовать кавычки для меток, указанных с помощью .loc
. Если их забыть, это приведет к NameError
.
Ошибка IndexError
может возникнуть при использовании .iloc
, если мы указываем целочисленную позицию, которая находится вне допустимого диапазона индексов нашего DataFrame. Это происходит, когда индекс, к которому вы пытаетесь получить доступ, не существует, либо потому, что он превышает количество строк или столбцов в вашем DataFrame, либо потому, что это отрицательное значение. Чтобы предотвратить эту ошибку, проверьте размеры вашего DataFrame и используйте соответствующие значения индексов в пределах допустимого диапазона.
Заключение
Надеюсь, этот блог был полезен, и различие между .loc
и .iloc
теперь ясно. Чтобы узнать больше, вот несколько хороших следующих шагов: