панды лок против илок против икс против у против иат?

Недавно начал переходить из моего безопасного места (R) в Python, и меня немного смущает локализация/выборка ячеек в Pandas. Я прочитал документацию, но изо всех сил пытаюсь понять практические последствия различных вариантов локализации/выбора.

  • Есть ли причина, по которой мне следует использовать .loc или .iloc наиболее общего варианта .ix?
  • Я понимаю, что .loc, iloc, at и iat могут обеспечить некоторую гарантированную корректность, .ix не может предложить .ix, но я также прочитал, где .ix имеет тенденцию быть самым быстрым решением из всех возможных.
  • Пожалуйста, объясните реальную практическую .ix использования чего-либо, кроме .ix?

Ответ 1

loc: только работа с индексом
iloc: работа на позиции
IX: вы можете получить данные из dataframe, не находясь в индексе
at: получить скалярные значения. Это очень быстрый лока
iat: получить скалярные значения. Это очень быстрый iloc

http://pyciencia.blogspot.com/2015/05/obtener-y-filtrar-datos-de-un-dataframe.html

Примечание. Начиная с pandas 0.20.0, индексатор .ix устарел в пользу более строгих индексаторов .iloc и .loc.

Ответ 2

Обновлено для pandas 0.20 при условии, что ix устарел. Это демонстрирует не только то, как использовать loc, iloc, at, iat, set_value, но как выполнить смешанную индексацию на основе позиционирования/метки.


loc - на основе меток
Позволяет передавать 1-D массивы в качестве индексаторов. Массивы могут быть либо срезами (подмножествами) индекса или столбца, либо они могут быть логическими массивами, которые равны по длине индексу или столбцам.

Специальное примечание: при передаче скалярного индексатора loc может назначить новое значение индекса или столбца, которое раньше не существовало.

# label based, but we can use position values
# to get the labels from the index object
df.loc[df.index[2], 'ColName'] = 3

df.loc[df.index[1:3], 'ColName'] = 3

iloc - позиция основана
Подобно loc, за исключением позиций, а не значений индекса. Однако вы не можете назначать новые столбцы или индексы.

# position based, but we can get the position
# from the columns object via the `get_loc` method
df.iloc[2, df.columns.get_loc('ColName')] = 3

df.iloc[2, 4] = 3

df.iloc[:3, 2:4] = 3

at - на основе меток
Работает очень похоже на loc для скалярных индексаторов. Невозможно работать с индексаторами массивов. Может! назначать новые индексы и столбцы.

Преимущество над loc заключается в том, что это быстрее.
Недостаток заключается в том, что вы не можете использовать массивы для индексаторов.

# label based, but we can use position values
# to get the labels from the index object
df.at[df.index[2], 'ColName'] = 3

df.at['C', 'ColName'] = 3

iat - позиция на основе
Работает аналогично iloc. Невозможно работать в индексах массива. Невозможно! назначить новые индексы и столбцы.

Преимущество над iloc заключается в том, что это быстрее.
Недостаток заключается в том, что вы не можете использовать массивы для индексаторов.

# position based, but we can get the position
# from the columns object via the `get_loc` method
IBM.iat[2, IBM.columns.get_loc('PNL')] = 3

set_value - на основе меток
Работает очень похоже на loc для скалярных индексаторов. Невозможно работать с индексаторами массивов. Может! назначать новые индексы и столбцы

Преимущество Супер быстрый, потому что накладных расходов очень мало!
Недостаток Накладные расходы очень мало, потому что pandas не выполняет кучу проверок безопасности. Использовать на свой страх и риск. Кроме того, это не предназначено для общественного пользования.

# label based, but we can use position values
# to get the labels from the index object
df.set_value(df.index[2], 'ColName', 3)

set_value с takable=True - позиция основана
Работает аналогично iloc. Невозможно работать в индексах массива. Невозможно! назначить новые индексы и столбцы.

Преимущество Супер быстрый, потому что накладных расходов очень мало!
Недостаток Накладные расходы очень мало, потому что pandas не выполняет кучу проверок безопасности. Использовать на свой страх и риск. Кроме того, это не предназначено для общественного пользования.

# position based, but we can get the position
# from the columns object via the `get_loc` method
df.set_value(2, df.columns.get_loc('ColName'), 3, takable=True)

Ответ 3

Есть два основных способа, которыми pandas делает выбор из DataFrame.

  • По метке
  • По целому расположению

В документации термин " позиция" используется для обозначения целочисленного местоположения. Мне не нравится эта терминология, поскольку я чувствую, что она сбивает с толку. Целочисленное местоположение является более .iloc и является именно тем, что обозначает .iloc. Ключевое слово здесь - INTEGER - вы должны использовать целые числа при выборе по целому расположению.

Прежде чем показывать резюме, убедитесь, что...

.ix устарела и неоднозначна и никогда не должна использоваться

Есть три основных индекса для панд. У нас есть сам оператор индексации (скобки []), .loc и .iloc. Давайте подведем их итоги:

  • [] - В первую очередь выбирает подмножества столбцов, но также может выбирать строки. Невозможно одновременно выбрать строки и столбцы.
  • .loc - выбирает подмножества строк и столбцов только по .loc
  • .iloc - выбирает подмножества строк и столбцов только по целому расположению

Я почти никогда не использую .at или .iat как они не добавляют никакой дополнительной функциональности и лишь незначительно увеличивают производительность. Я бы не рекомендовал их использовать, если у вас нет очень чувствительного ко времени приложения. Несмотря на это, у нас есть их резюме:

  • .at выбирает одно скалярное значение в DataFrame только по метке
  • .iat выбирает единственное скалярное значение в DataFrame только по целому расположению

В дополнение к выбору по метке и целочисленному местоположению существует логическое выделение, также известное как логическое индексирование.


Примеры, поясняющие .loc, .iloc, логический выбор и .at и .iat показаны ниже

Сначала мы сосредоточимся на различиях между .loc и .iloc. Прежде чем говорить о различиях, важно понять, что в фреймах данных есть метки, которые помогают идентифицировать каждый столбец и каждую строку. Давайте посмотрим на пример DataFrame:

df = pd.DataFrame({'age':[30, 2, 12, 4, 32, 33, 69],
                   'color':['blue', 'green', 'red', 'white', 'gray', 'black', 'red'],
                   'food':['Steak', 'Lamb', 'Mango', 'Apple', 'Cheese', 'Melon', 'Beans'],
                   'height':[165, 70, 120, 80, 180, 172, 150],
                   'score':[4.6, 8.3, 9.0, 3.3, 1.8, 9.5, 2.2],
                   'state':['NY', 'TX', 'FL', 'AL', 'AK', 'TX', 'TX']
                   },
                  index=['Jane', 'Nick', 'Aaron', 'Penelope', 'Dean', 'Christina', 'Cornelia'])

enter image description here

Все слова, выделенные жирным шрифтом, являются метками. Метки, age, color, food, height, score и state используются для столбцов. Другие метки, Jane, Nick, Aaron, Penelope, Dean, Christina, Cornelia, используются в качестве меток для строк. В совокупности эти метки строк известны как индекс.


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

.loc выбирает данные только по меткам

Сначала поговорим о индексаторе .loc который выбирает данные только по меткам индекса или столбца. В нашем примере DataFrame мы предоставили значимые имена в качестве значений для индекса. Многие DataFrames не будут иметь каких-либо значимых имен и вместо этого по умолчанию будут просто целыми числами от 0 до n-1, где n - длина (количество строк) DataFrame.

Есть много разных входов, которые вы можете использовать для .loc из них три

  • Строка
  • Список строк
  • Запись среза с использованием строк в качестве начального и конечного значений

Выбор одной строки с помощью .loc со строкой

Чтобы выбрать одну строку данных, поместите индексную метку внутри скобок после .loc.

df.loc['Penelope']

Это возвращает строку данных в виде серии

age           4
color     white
food      Apple
height       80
score       3.3
state        AL
Name: Penelope, dtype: object

Выбор нескольких строк с помощью .loc со списком строк

df.loc[['Cornelia', 'Jane', 'Dean']]

Это возвращает DataFrame со строками в порядке, указанном в списке:

enter image description here

Выбор нескольких строк с помощью .loc с обозначением слайса

Обозначение среза определяется значениями start, stop и step. При разрезании по метке pandas включает в себя значение остановки в возвращаемом значении. Следующие кусочки от Аарона до Дина включительно. Размер шага явно не определен, но по умолчанию равен 1.

df.loc['Aaron':'Dean']

enter image description here

Сложные фрагменты могут быть взяты так же, как списки Python.

.iloc выбирает данные только по целому расположению

Давай теперь обратимся к .iloc. Каждая строка и столбец данных в DataFrame имеет целочисленное расположение, которое определяет его. Это в дополнение к метке, которая визуально отображается в выходных данных. Целочисленное местоположение - это просто число строк/столбцов сверху/слева, начиная с 0.

Есть много разных входов, которые вы можете использовать для .iloc Три из них:

  • Целое число
  • Список целых чисел
  • Срезовая запись с использованием целых чисел в качестве начального и конечного значений

Выбор одной строки с .iloc с целым числом

df.iloc[4]

Это возвращает 5-ую строку (целочисленное местоположение 4) как серию

age           32
color       gray
food      Cheese
height       180
score        1.8
state         AK
Name: Dean, dtype: object

Выбор нескольких строк с .iloc со списком целых чисел

df.iloc[[2, -2]]

Это возвращает DataFrame третьей и второй до последней строки:

enter image description here

Выбор нескольких строк с .iloc с обозначением среза

df.iloc[:5:3]

enter image description here


Одновременный выбор строк и столбцов с .loc и .iloc

Одной из отличных способностей обоих .loc/.iloc является их способность выбирать строки и столбцы одновременно. В приведенных выше примерах все столбцы возвращались из каждого выбора. Мы можем выбрать столбцы с теми же типами входов, что и для строк. Нам просто нужно разделить выбор строки и столбца запятой.

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

df.loc[['Jane', 'Dean'], 'height':]

enter image description here

При этом используется список меток для строк и нотации для столбцов

Естественно, мы можем делать аналогичные операции с .iloc используя только целые числа.

df.iloc[[1,4], 2]
Nick      Lamb
Dean    Cheese
Name: food, dtype: object

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

.ix использовался, чтобы делать выборки одновременно с метками и целочисленным местоположением, что было полезно, но .ix с толку и неоднозначно, и, к счастью, это не рекомендуется. В случае, если вам нужно сделать выборку с сочетанием меток и целочисленных местоположений, вам нужно будет сделать метки выбора или целочисленные местоположения.

Например, если мы хотим выбрать строки Nick и Cornelia вместе со столбцами 2 и 4, мы могли бы использовать .loc, преобразовав целые числа в метки со следующим:

col_names = df.columns[[2, 4]]
df.loc[['Nick', 'Cornelia'], col_names] 

Или, в качестве альтернативы, преобразуйте метки индекса в целые числа с помощью get_loc индекса get_loc.

labels = ['Nick', 'Cornelia']
index_ints = [df.index.get_loc(label) for label in labels]
df.iloc[index_ints, [2, 4]]

Логическое выделение

Индексатор .loc также может выполнять логический выбор. Например, если мы заинтересованы в том, чтобы найти все строки, в которых возраст превышает 30 лет, и вернуть только столбцы " food и " score мы можем сделать следующее:

df.loc[df['age'] > 30, ['food', 'score']] 

Вы можете повторить это с помощью .iloc но не можете передать его логическим сериям. Вы должны преобразовать логическую серию в массив numpy следующим образом:

df.iloc[(df['age'] > 30).values, [2, 4]] 

Выбор всех строк

Можно использовать .loc/.iloc только для выбора столбца. Вы можете выбрать все строки, используя двоеточие, как это:

df.loc[:, 'color':'score':2]

enter image description here


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

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

df['food']

Jane          Steak
Nick           Lamb
Aaron         Mango
Penelope      Apple
Dean         Cheese
Christina     Melon
Cornelia      Beans
Name: food, dtype: object

Использование списка выбирает несколько столбцов

df[['food', 'score']]

enter image description here

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

df['Penelope':'Christina'] # slice rows by label

enter image description here

df[2:6:2] # slice rows by integer location

enter image description here

.loc/.iloc для выбора строк очень предпочтительна. Один оператор индексирования не может одновременно выбирать строки и столбцы.

df[3:5, 'color']
TypeError: unhashable type: 'slice'

Выбор по .at и .iat

Выбор с .at почти идентичен .loc но он выбирает только одну "ячейку" в вашем DataFrame. Мы обычно называем эту ячейку скалярным значением. Чтобы использовать .at, передайте метку строки и столбца через запятую.

df.at['Christina', 'color']
'black'

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

df.iat[2, 5]
'FL'

Ответ 4

df = pd.DataFrame({'A':['a', 'b', 'c'], 'B':[54, 67, 89]}, index=[100, 200, 300])

df

                        A   B
                100     a   54
                200     b   67
                300     c   89
In [19]:    
df.loc[100]

Out[19]:
A     a
B    54
Name: 100, dtype: object

In [20]:    
df.iloc[0]

Out[20]:
A     a
B    54
Name: 100, dtype: object

In [24]:    
df2 = df.set_index([df.index,'A'])
df2

Out[24]:
        B
    A   
100 a   54
200 b   67
300 c   89

In [25]:    
df2.ix[100, 'a']

Out[25]:    
B    54
Name: (100, a), dtype: int64

Ответ 5

Давайте начнем с этого небольшого df:

import pandas as pd
import time as tm
import numpy as np
n=10
a=np.arange(0,n**2)
df=pd.DataFrame(a.reshape(n,n))

У нас так будет

df
Out[25]: 
        0   1   2   3   4   5   6   7   8   9
    0   0   1   2   3   4   5   6   7   8   9
    1  10  11  12  13  14  15  16  17  18  19
    2  20  21  22  23  24  25  26  27  28  29
    3  30  31  32  33  34  35  36  37  38  39
    4  40  41  42  43  44  45  46  47  48  49
    5  50  51  52  53  54  55  56  57  58  59
    6  60  61  62  63  64  65  66  67  68  69
    7  70  71  72  73  74  75  76  77  78  79
    8  80  81  82  83  84  85  86  87  88  89
    9  90  91  92  93  94  95  96  97  98  99

С этим мы имеем:

df.iloc[3,3]
Out[33]: 33

df.iat[3,3]
Out[34]: 33

df.iloc[:3,:3]
Out[35]: 
    0   1   2   3
0   0   1   2   3
1  10  11  12  13
2  20  21  22  23
3  30  31  32  33



df.iat[:3,:3]
Traceback (most recent call last):
   ... omissis ...
ValueError: At based indexing on an integer index can only have integer indexers

Таким образом, мы не можем использовать .iat для подмножества, где мы должны использовать только .iloc.

Но давайте попробуем оба выбрать больший df и проверить скорость...

# -*- coding: utf-8 -*-
"""
Created on Wed Feb  7 09:58:39 2018

@author: Fabio Pomi
"""

import pandas as pd
import time as tm
import numpy as np
n=1000
a=np.arange(0,n**2)
df=pd.DataFrame(a.reshape(n,n))
t1=tm.time()
for j in df.index:
    for i in df.columns:
        a=df.iloc[j,i]
t2=tm.time()
for j in df.index:
    for i in df.columns:
        a=df.iat[j,i]
t3=tm.time()
loc=t2-t1
at=t3-t2
prc = loc/at *100
print('\nloc:%f at:%f prc:%f' %(loc,at,prc))

loc:10.485600 at:7.395423 prc:141.784987

Таким образом, с помощью .loc мы можем управлять подмножествами, а с помощью .at - только одним скаляром, но .at быстрее, чем .loc

:-)