python pandas - dataframe - индексирование [дубликат]

«Конечно, до тех пор, пока вы выделяете память в куче», - где выделенная память не имеет к этому никакого отношения. Это все о семантике. Возьмем, например:

Derived d;
Base* b = &d;

d находится в стеке (автоматическая память), но полиморфизм будет по-прежнему работать на b.

Если у вас нет указатель базового класса или ссылка на производный класс, полиморфизм не работает, потому что у вас больше нет производного класса. Take

Base c = Derived();

Объект c не является Derived, а Base из-за нарезки. Итак, технически, полиморфизм все еще работает, просто у вас больше нет объекта Derived.

Теперь возьмите

Base* c = new Derived();

c, просто указывая на некоторые место в памяти, и вам все равно, действительно ли это Base или Derived, но вызов метода virtual будет разрешен динамически.

379
задан smci 22 February 2018 в 08:47
поделиться

3 ответа

Примечание: в версии pandas 0.20.0 и выше ix является устаревшим , и вместо этого рекомендуется использовать loc и iloc. Я оставил части этого ответа, которые описывают ix в качестве ссылки для пользователей более ранних версий панд. Примеры были добавлены ниже, показывая альтернативы ix .


Сначала рассмотрим три метода:

  • loc получает строки (или столбцы) с конкретными метками из индекса.
  • iloc получает строки (или столбцы) в определенных положениях в индексе (поэтому он принимает только целые числа).
  • ix обычно пытается например, loc, но возвращается к тому, чтобы вести себя как iloc, если метка отсутствует в индексе.

Важно отметить некоторые тонкости, которые могут сделать ix немного сложнее use:

  • , если индекс имеет целочисленный тип, ix будет использовать индексирование на основе меток и не возвращаться к индексированию на основе позиции. Если метка не указана в индексе, возникает ошибка.
  • , если индекс не содержит целых чисел только , а затем задает целое число, ix немедленно будет использовать позицию- а не индексации на основе меток. Если, однако, ix задан другой тип (например, строка), он может использовать индексирование на основе меток.

Чтобы проиллюстрировать различия между тремя методами, рассмотрим следующую серию :

>>> s = pd.Series(np.nan, index=[49,48,47,46,45, 1, 2, 3, 4, 5])
>>> s
49   NaN
48   NaN
47   NaN
46   NaN
45   NaN
1    NaN
2    NaN
3    NaN
4    NaN
5    NaN

Мы рассмотрим срез с целым значением 3.

В этом случае s.iloc[:3] возвращает нам первые 3 строки (так как он обрабатывает 3 как позиция), а s.loc[:3] возвращает нам первые 8 строк (так как он рассматривает 3 как метку):

>>> s.iloc[:3] # slice the first three rows
49   NaN
48   NaN
47   NaN

>>> s.loc[:3] # slice up to and including label 3
49   NaN
48   NaN
47   NaN
46   NaN
45   NaN
1    NaN
2    NaN
3    NaN

>>> s.ix[:3] # the integer is in the index so s.ix[:3] works like loc
49   NaN
48   NaN
47   NaN
46   NaN
45   NaN
1    NaN
2    NaN
3    NaN

Уведомление s.ix[:3] возвращает ту же серию, что и s.loc[:3], поскольку она ищет метка сначала, а не работа над позицией (и индекс для s имеет целочисленный тип).

Что делать, если мы попытаемся использовать целую метку, которая не находится в индексе (скажем, 6 )?

Здесь s.iloc[:6] возвращает первые 6 строк Серии, как ожидалось. Однако s.loc[:6] вызывает KeyError, поскольку 6 не находится в индексе.

>>> s.iloc[:6]
49   NaN
48   NaN
47   NaN
46   NaN
45   NaN
1    NaN

>>> s.loc[:6]
KeyError: 6

>>> s.ix[:6]
KeyError: 6

В соответствии с отмеченными выше тонкостями s.ix[:6] теперь вызывает KeyError, потому что он пытается работать как loc, но не может найти 6 в индексе. Поскольку наш индекс имеет целочисленный тип ix, он не возвращается к поведению, как iloc.

Если, однако, наш индекс был смешанного типа, то целое число ix будет вести себя как iloc немедленно, вместо того, чтобы поднимать KeyError:

>>> s2 = pd.Series(np.nan, index=['a','b','c','d','e', 1, 2, 3, 4, 5])
>>> s2.index.is_mixed() # index is mix of different types
True
>>> s2.ix[:6] # now behaves like iloc given integer
a   NaN
b   NaN
c   NaN
d   NaN
e   NaN
1   NaN

Имейте в виду, что ix все еще могут принимать нецелые числа и вести себя как loc:

>>> s2.ix[:'c'] # behaves like loc given non-integer
a   NaN
b   NaN
c   NaN

As общие рекомендации, если вы используете только индексирование с использованием меток или только индексирование с использованием целых позиций, придерживайтесь loc или iloc, чтобы избежать неожиданных результатов. Не пытайтесь использовать ix.


Комбинирование индексирования на основе позиции и метки на основе меток

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

Например, рассмотрим следующие DataFrame. Как лучше всего разрезать строки до и включая «c» и взять первые четыре столбца?

>>> df = pd.DataFrame(np.nan, 
                      index=list('abcde'),
                      columns=['x','y','z', 8, 9])
>>> df
    x   y   z   8   9
a NaN NaN NaN NaN NaN
b NaN NaN NaN NaN NaN
c NaN NaN NaN NaN NaN
d NaN NaN NaN NaN NaN
e NaN NaN NaN NaN NaN

В более ранних версиях панд (до 0.20.0) ix позволяет сделать это довольно аккуратно - мы можем нарезать строки по метке и столбцам по положению (обратите внимание, что для столбцов ix по умолчанию будет использоваться резка на основе положения, поскольку 4 не является именем столбца):

>>> df.ix[:'c', :4]
    x   y   z   8
a NaN NaN NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN

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

>>> df.iloc[:df.index.get_loc('c') + 1, :4]
    x   y   z   8
a NaN NaN NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN

get_loc() это индексный метод, означающий «получить позицию метки в этом индексе». Обратите внимание, что поскольку нарезка с iloc не является конечной точкой, мы должны добавить 1 к этому значению, если хотим также строку 'c'.

В документации pandas есть дополнительные примеры .

607
ответ дан Alex Riley 16 August 2018 в 04:32
поделиться
  • 1
    Это тот пример, который был бы полезен в документах. – AZhao 23 July 2015 в 17:57
  • 2
    Отличное объяснение! Один связанный с ним вопрос, который у меня всегда был, - какое отношение, если таковые имеются, loc, iloc и ix имеют предупреждения SettingWithCopy? Существует некоторая документация, но, честно говоря, я все еще немного смущен pandas.pydata.org/pandas-docs/stable/… – measureallthethings 23 July 2015 в 18:36
  • 3
    @measurealltheings: loc, iloc и ix могут по-прежнему вызывать предупреждение, если они соединены вместе. Используя пример DataFrame в связанных документах dfmi.loc[:, 'one'].loc[:, 'second'], запускается предупреждение так же, как dfmi['one']['second'], потому что копия данных (а не представление) может быть возвращена первой операцией индексирования. – Alex Riley 23 July 2015 в 18:56
  • 4
    Я думаю, что последний пример не совсем корректен, потому что в df.ix[1:3, :'b'] оба этикета основаны на ярлыках. BTW, всегда приветствуем, чтобы улучшить документы, чтобы сделать вещи более ясными! – joris 24 July 2015 в 14:52
  • 5
    Спасибо @joris - я обновил / исправил пример. Я определенно был бы рад взглянуть на документы когда-нибудь, чтобы увидеть, есть ли что-нибудь, что я могу внести ... – Alex Riley 24 July 2015 в 15:04

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

df.iloc[0]

или последние пять строк, выполнив

df.iloc[-5:]

. Вы можете также используйте его на столбцах. Это извлекает третий столбец:

df.iloc[:, 2]    # the : in the first position indicates all rows

Вы можете комбинировать их для получения пересечений строк и столбцов:

df.iloc[:3, :3] # The upper-left 3 X 3 entries (assuming df has 3+ rows and columns)

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

df = pd.DataFrame(index=['a', 'b', 'c'], columns=['time', 'date', 'name'])

Затем мы можем получить первую строку по

df.loc['a']     # equivalent to df.iloc[0]

, а вторую две строки в 'date' столбца

df.loc['b':, 'date']   # equivalent to df.iloc[1:, 1]

и т. д. Теперь, вероятно, стоит отметить, что индексы строк и столбцов по умолчанию для DataFrame являются целыми числами от 0, и в этом случае iloc и loc будут работать одинаково. Вот почему ваши три примера эквивалентны. Если у вас был нечисловой индекс, такой как строки или даты, df.loc[:5] вызовет ошибку.

Кроме того, вы можете выполнить поиск столбцов только с помощью фрейма данных __getitem__:

df['time']    # equivalent to df.loc[:, 'time']

Теперь предположим, что вы хотите смешать позицию и названную индексацию, то есть индексирование с использованием имена в строках и позициях в столбцах (чтобы уточнить, я имею в виду выбор из нашего фрейма данных, а не создание фрейма данных со строками в индексе строки и целых чисел в индексе столбца). Вот где .ix приходит:

df.ix[:2, 'time']    # the first two rows of the 'time' column

EDIT: Я думаю, что также стоит упомянуть, что вы можете передавать логические векторы в метод loc. Например:

 b = [True, False, True]
 df.loc[b] 

Вернет 1-ю и 3-ю строки df. Это эквивалентно df[b] для выбора, но его также можно использовать для назначения через логические векторы:

df.loc[b, 'name'] = 'Mary', 'John'
80
ответ дан Merlin 16 August 2018 в 04:32
поделиться
  • 1
    Является ли df.iloc [:,:] эквивалентным всем строкам и столбцам? – Alvis 3 May 2017 в 10:03
  • 2
    Это, как и df.loc[:, :]. Его можно использовать для повторного назначения значений всего DataFrame или создания его вида. – JoeCondron 3 May 2017 в 20:45
  • 3
    Мне больше всего понравился этот ответ. – renakre 14 September 2017 в 09:16
43
ответ дан Mr_and_Mrs_D 16 August 2018 в 04:32
поделиться
Другие вопросы по тегам:

Похожие вопросы: