Свойство
.loc[]
и.iloc[]
является основным методом доступа к данным вpandas.DataFrame
иpandas.Series
.
DataFrame.loc[]
- доступ к срезу данных DataFrame
по индексным меткам;Series.loc[]
- доступ к срезу данных Series
по индексным меткам;DataFrame.iloc[]
- доступ к срезу данных DataFrame
по позиции;Series.iloc[]
- доступ к срезу данных Series
по позиции;Series
/DataFrame
;Необходимо понимать отличие индексной метки от целочисленной позиции (например, как позиция элемента в списке Python). Индексные метки строк могут совпадать с целочисленной позицией строк, если
DataFrame
илиSeries
создается без указания аргументаindex
.
Series.loc[]
:DataFrame.loc[]
:Свойство DataFrame.loc[]
и Series.loc[]
осуществляет доступ к группе строк и столбцов по их индексным меткам или может использоваться с логическим массивом.
Допустимые входные данные:
'a'
. Обратите внимание, что 5 интерпретируется как метка индекса, а не как целочисленная позиция вдоль индекса.['a', 'b', 'c']
.'a':'f'
. Обратите внимание, что в отличие от обычных срезов python, включены как начало, так и конец.[True, False, True]
.Series
или DataFrame
), которая возвращает допустимые данные для индексирования (одно из приведенных выше)Возникающие исключения:
KeyError
- если какие-либо элементы не найдены.IndexingError
- если передан индексированный ключ, и его индекс не соответствует индексу кадра.DataFrame.loc[]
и Series.loc[]
:DataFrame
;DataFrame
;MultiIndex
.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
для столбцов). Свойство также может использоваться с массивом логических значений той же длины, что и индекс строк/столбцов.
Разрешенные входные данные:
[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