Сообщить об ошибке.

Свойства .loc[], .iloc[] объектов Series/DataFrame в pandas

Доступ к данных Series/DataFrame по меткам и/или позиции в pandas

Свойство .loc[] и .iloc[] является основным методом доступа к данным в pandas.DataFrame и pandas.Series.

Содержание:

Необходимо понимать отличие индексной метки от целочисленной позиции (например, как позиция элемента в списке Python). Индексные метки строк могут совпадать с целочисленной позицией строк, если DataFrame или Series создается без указания аргумента index.


Series.loc[]:
DataFrame.loc[]:

Свойство DataFrame.loc[] и Series.loc[] осуществляет доступ к группе строк и столбцов по их индексным меткам или может использоваться с логическим массивом.

Допустимые входные данные:

  • Одна метка, например, 5 или 'a'. Обратите внимание, что 5 интерпретируется как метка индекса, а не как целочисленная позиция вдоль индекса.
  • Список или массив меток, например ['a', 'b', 'c'].
  • Объект-срез с метками, например 'a':'f'. Обратите внимание, что в отличие от обычных срезов python, включены как начало, так и конец.
  • массив логических значений той же длины, что и разрезаемая ось (строка/столбец), например [True, False, True].
  • Выравниваемый логический ряд. Индекс ключа будет выровнен перед наложением маски.
  • Выравниваемый индекс. Возвращаемый индекс будет являться входными данными.
  • Вызываемый объект с одним аргументом (Series или DataFrame), которая возвращает допустимые данные для индексирования (одно из приведенных выше)

Возникающие исключения:

  • KeyError - если какие-либо элементы не найдены.
  • IndexingError - если передан индексированный ключ, и его индекс не соответствует индексу кадра.

Доступ к данным при помощи свойств DataFrame.loc[] и Series.loc[]:

Получение/извлечение значений Series/DataFrame

>>> import pandas as pd
# обратите внимание, что при создании 
# `DataFrame` указывается индекс строк 
>>> df = pd.DataFrame([[1, 2], [4, 5], [7, 8]],
...      index=['cobra', 'viper', 'sidewinder'],
...      columns=['max_speed', 'shield'])
>>> df
#             max_speed  shield
# cobra               1       2
# viper               4       5
# sidewinder          7       8

Одиночная индексная метка. Обратите внимание, что это возвращает строку как Series.

>>> df.loc['viper']
# max_speed    4
# shield       5
# Name: viper, dtype: int64

Обратите внимание, что получение значений в DataFrame с помощью индекса с целочисленными метками работает аналогичным образом. Прото необходимо понять, что индексная метка - это не позиция (например как позиция элемента в списке Python, которая начинается с 0).

# обратите внимание, что при создании 
# `DataFrame` указывается индекс строк 
>>> df1 = pd.DataFrame([[1, 2], [4, 5], [7, 8]],
...      index=[7, 8, 9], columns=['max_speed', 'shield'])
>>> df1
#    max_speed  shield
# 7          1       2
# 8          4       5
# 9          7       8

>>> df1.loc[8]
# max_speed    4
# shield       5
# Name: 8, dtype: int64

Список индексных меток. Обратите внимание, что использование [[]] возвращает DataFrame.

>>> df.loc[['viper', 'sidewinder']]
#             max_speed  shield
# viper               4       5
# sidewinder          7       8

По одной индексной метке для строки и столбца.

>>> df.loc['cobra', 'shield']
# 2

Срез с метками для строки и одной меткой для столбца. Обратите внимание, что включены как начало, так и конец среза.

>>> df.loc['cobra':'viper', 'max_speed']
# cobra    1
# viper    4
# Name: max_speed, dtype: int64

Список из логических значений той же длины, что и ось строк:

>>> df.loc[[False, False, True]]
#             max_speed  shield
# sidewinder          7       8

Серия из логических значений, выравниваемая по индексным меткам строк:

>>> df.loc[pd.Series([False, True, False], index=['viper', 'sidewinder', 'cobra'])]
#             max_speed  shield
# sidewinder          7       8

Использование Index (то же поведение, что и у метода df.reindex())

>>> df.loc[pd.Index(["cobra", "viper"], name="foo")]
#        max_speed  shield
# foo
# cobra          1       2
# viper          4       5

Условие, возвращающее серию из логических значений

>>> df.loc[df['shield'] > 6]
#             max_speed  shield
# sidewinder          7       8

Условие, возвращающее серию из логических значений с указанными метками столбцов.

>>> df.loc[df['shield'] > 6, ['max_speed']]
#             max_speed
# sidewinder          7

Множественное условие с использованием & (логическое И), которое возвращает серию из логических значений.

>>> df.loc[(df['max_speed'] > 1) & (df['shield'] < 8)]
#        max_speed  shield
# viper          4       5

Множественное условие с использованием | (логическое ИЛИ), которое возвращает серию из логических значений. Обратите внимание, что каждое условие заключено в круглые скобки ().

>>> df.loc[(df['max_speed'] > 4) | (df['shield'] < 5)]
#             max_speed  shield
# cobra               1       2
# sidewinder          7       8

Внимание! Если в DataFrame.loc[] используется 3 или более условных выражений, то лучше рассмотреть возможность использования расширенного индексирования.

Использование вызываемого объекта на примере lambda-функции, которая возвращает серию из логических значений:

>>> df.loc[lambda df: df['shield'] == 8]
#             max_speed  shield
# sidewinder          7       8

Установка значений Series/DataFrame

Установить значение для всех элементов, соответствующих списку меток

>>> df.loc[['viper', 'sidewinder'], ['shield']] = 50
>>> df
#             max_speed  shield
# cobra               1       2
# viper               4      50
# sidewinder          7      50

Установить значение для всей строки

>>> df.loc['cobra'] = 10
>>> df
#             max_speed  shield
# cobra              10      10
# viper               4      50
# sidewinder          7      50

Установить значение для всего столбца

>>> df.loc[:, 'max_speed'] = 30
>>> df
#             max_speed  shield
# cobra              30      10
# viper              30      50
# sidewinder         30      50

Добавить значение, соответствующее местоположению ячейки

>>> df.loc["viper", "shield"] += 5
>>> df
#             max_speed  shield
# cobra              30      10
# viper               0       5
# sidewinder          0       0

Использование Series или DataFrame устанавливает значения, соответствующие меткам индекса, а не позициям индекса.

>>> shuffled_df = df.loc[["viper", "cobra", "sidewinder"]]
>>> df.loc[:] += shuffled_df
>>> df
#             max_speed  shield
# cobra              60      20
# viper               0      10
# sidewinder          0       0

Получение значений с помощью MultiIndex

Несколько примеров использования DataFrame с MultiIndex

tuples = [
   ('cobra', 'mark i'), ('cobra', 'mark ii'),
   ('sidewinder', 'mark i'), ('sidewinder', 'mark ii'),
   ('viper', 'mark ii'), ('viper', 'mark iii')
]
>>> index = pd.MultiIndex.from_tuples(tuples)
>>> values = [[12, 2], [0, 4], [10, 20], [1, 4], [7, 1], [16, 36]]
>>> df = pd.DataFrame(values, columns=['max_speed', 'shield'], index=index)
>>> df
#                      max_speed  shield
# cobra      mark i           12       2
#            mark ii           0       4
# sidewinder mark i           10      20
#            mark ii           1       4
# viper      mark ii           7       1
#            mark iii         16      36

Одиночная индексная метка. Обратите внимание, что это возвращает DataFrame с одним индексом.

>>> df.loc['cobra']
#          max_speed  shield
# mark i          12       2
# mark ii          0       4

Кортеж с единым индексом. Обратите внимание, что возвращается Series.

>>> df.loc[('cobra', 'mark ii')]
# max_speed    0
# shield       4
# Name: (cobra, mark ii), dtype: int64

Одна индексная метка для строки и столбца. Подобно передаче кортежа, возвращается Series.

>>> df.loc['cobra', 'mark i']
# max_speed    12
# shield        2
# Name: (cobra, mark i), dtype: int64

Одиночный кортеж. Обратите внимание, что использование [[]] возвращает DataFrame.

>>> df.loc[[('cobra', 'mark ii')]]
#                max_speed  shield
# cobra mark ii          0       4

Одиночный кортеж для индекса с одной меткой для столбца.

>>> df.loc[('cobra', 'mark i'), 'shield']
# 2

Срез от индексного кортежа до одной метки

>>> df.loc[('cobra', 'mark i'):'viper']
#                      max_speed  shield
# cobra      mark i           12       2
#            mark ii           0       4
# sidewinder mark i           10      20
#            mark ii           1       4
# viper      mark ii           7       1
#            mark iii         16      36

Срез от индексного кортежа к индексному кортежу

>>> df.loc[('cobra', 'mark i'):('viper', 'mark ii')]
#                     max_speed  shield
# cobra      mark i          12       2
#            mark ii          0       4
# sidewinder mark i          10      20
#            mark ii          1       4
# viper      mark ii          7       1

Series.iloc[]:
DataFrame.iloc[]:

Чисто целочисленная индексация на основе местоположения для выбора по позиции.

Свойство DataFrame.iloc[] и Series.iloc[] осуществляет доступ к группе строк и столбцов по целочисленной позиции (от 0 до len(DataFrame.index)-1 (len(Series.index)-1) для строк и от 0 до len(DataFrame.columns)-1 для столбцов). Свойство также может использоваться с массивом логических значений той же длины, что и индекс строк/столбцов.

Разрешенные входные данные:

  • Целое число, например 5.
  • Список или массив целых чисел, например. [4, 3, 0].
  • Объект среза с целыми числами, например. 1:7.
  • Массив логических значений той же длины, что и разрезаемая ось (строка/столбец), например [True, False, True].
  • Вызываемый объект с одним аргументом (принимает Series или DataFrame) и возвращающая действительный результат для индексации (один из вышеперечисленных). Такое поведение полезно в цепочках методов, когда нет ссылки на вызывающий объект, при этом необходимо основывать свой выбор на каком-то значении.
  • Кортеж индексов строк и столбцов. Элементы кортежа состоят из одного из вышеуказанных входных данных, например, (0, 1).

Возникающие исключения:

DataFrame.iloc[] и Series.iloc[] вызовет IndexError, если запрошенный индекс находится за пределами границ, за исключением индексов в срезах, которые допускают индексацию за пределами границ (это соответствует семантике срезов python/numpy).

Доступ к данным при помощи свойств DataFrame.iloc[] и Series.iloc[]:

Обратите внимание, что при создании DataFrame аргумент index не указывается, следовательно индексные метки и позиции строк будут совпадать. Также обратите внимание, что НЕ совпадающие или буквенные индексные метки работают аналогичным образом (помним, что метод .iloc работает по позициям).

>>> import pandas as pd
>>> mydict = [{'a': 1, 'b': 2, 'c': 3, 'd': 4},
...           {'a': 100, 'b': 200, 'c': 300, 'd': 400},
...           {'a': 1000, 'b': 2000, 'c': 3000, 'd': 4000 }]
>>> df = pd.DataFrame(mydict, )
>>> df
#       a     b     c     d
# 0     1     2     3     4
# 1   100   200   300   400
# 2  1000  2000  3000  4000

Индексирование только строк

Со скалярным целым числом.

>>> type(df.iloc[0])
# <class 'pandas.core.series.Series'>
>>> df.iloc[0]
# a    1
# b    2
# c    3
# d    4
# Name: 0, dtype: int64

Со списком целых чисел.

>>> df.iloc[[0]]
#    a  b  c  d
# 0  1  2  3  4
>>> type(df.iloc[[0]])
# <class 'pandas.core.frame.DataFrame'>

>>> df.iloc[[0, 1]]
#      a    b    c    d
# 0    1    2    3    4
# 1  100  200  300  400

С объектом среза.

>>> df.iloc[:3]
#       a     b     c     d
# 0     1     2     3     4
# 1   100   200   300   400
# 2  1000  2000  3000  4000

С логической маской той же длины, что и индекс строк.

>>> df.iloc[[True, False, True]]
#       a     b     c     d
# 0     1     2     3     4
# 2  1000  2000  3000  4000

С вызываемым объектом, полезным в цепочках методов. Аргумент x, переданный в lambda-функцию, представляет собой срез DataFrame. При этом выбираются строки, индексная метка которых четная.

>>> df.iloc[lambda x: x.index % 2 == 0]
#       a     b     c     d
# 0     1     2     3     4
# 2  1000  2000  3000  4000

Индексирование обеих осей DataFrame

Можно смешивать типы индексов для строк и столбцов. Чтобы выбрать всю ось необходимо использовать :.

Со скалярными целыми числами.

>>> df.iloc[0, 1]
# 2

Со списками целых чисел.

>>> df.iloc[[0, 2], [1, 3]]
#       b     d
# 0     2     4
# 2  2000  4000

С объектами среза.

>>> df.iloc[1:3, 0:3]
#       a     b     c
# 1   100   200   300
# 2  1000  2000  3000

С логическим массивом, длина которого соответствует количеству столбцов. Обратите внимание, что для выбора всех строк используется срез :

>>> df.iloc[:, [True, False, True, False]]
#       a     c
# 0     1     3
# 1   100   300
# 2  1000  3000

С вызываемой функцией, которая ожидает Series или DataFrame.

>>> df.iloc[:, lambda df: [0, 2]]
#       a     c
# 0     1     3
# 1   100   300
# 2  1000  3000

Сочетание индексных меток и позиционной индексации в Series/DataFrame

Доступ к меткам строк и столбцов можно получить соответственно, обратившись к атрибутам индекса DataFrame.index и столбца DataFrame.columns:

>>> tmp = pd.DataFrame({'A': [1, 2, 3], 'B': [4, 5, 6]}, index=list('abc'))
>>> tmp
#    A  B
# a  1  4
# b  2  5
# c  3  6

>>> tmp.index
# Index(['a', 'b', 'c'], dtype='object')
>>> tmp.columns
# Index(['A', 'B'], dtype='object')

Владея этой информацией можно получить 0-й и 2-й элементы из индекса строк в столбце ‘A’ или первые 2 строки:

# 0-й и 2-й элементы из индекса строк в столбце ‘A’ 
>>> tmp.loc[tmp.index[[0, 2]], 'A']
# a    1
# c    3
# Name: A, dtype: int64

# или срез первых 2 строк
>>> tmp.loc[tmp.index[:2], 'A']
# a    1
# b    2
# Name: A, dtype: int64

Это также может быть выражено с помощью .iloc, путем явного получения местоположений в индексаторах и использования позиционной индексации для выбора объектов.

>>> tmp.iloc[[0, 2], tmp.columns.get_loc('A')]
# a    1
# c    3
# Name: A, dtype: int64

Для получения нескольких индексаторов необходимо использовать .get_indexer:

>>> tmp.iloc[[0, 2], tmp.columns.get_indexer(['A', 'B'])]
#    A  B
# a  1  4
# c  3  6