Iloc против Loc в Pandas: руководство с примерами

Одной из тех надоедливых вещей, которые мы все пытаемся понять, когда изучаем 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

Есть две вещи, о которых следует помнить:

  1. Вывод включает строку, указанную в row_label_end. Это отличается от .iloc, который мы рассмотрим позже.
  2. Мы используем только одну пару квадратных скобок, даже если хотим получить несколько строк. Мы не используем список для указания различных строк, поэтому использование двух квадратных скобок приведет к ошибке 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 теперь ясно. Чтобы узнать больше, вот несколько хороших следующих шагов:

Source:
https://www.datacamp.com/tutorial/loc-vs-iloc