2016-03-24 2 views
2

Допустим, у меня есть панд Series, и я хочу, чтобы получить доступ к набору элементов в конкретных показателях, например, так:Панды методы индексатор и кортежи в качестве параметров

In [1]: 
from pandas import Series 
import numpy as np 

s = Series(np.arange(0,10)) 

In [2]: s.loc[[3,7]] 

Out[2]: 
3 3 
7 7 
dtype: int64 

Метод .loc принимает list в качестве параметра для этого типа выбора. Методы .iloc и .ix работают одинаково.

Однако, если я использую tuple для параметра, как .loc и .iloc неудачу:

In [5]: s.loc[(3,7)] 
--------------------------------------------------------------------------- 
IndexingError        Traceback (most recent call last) 
........ 
IndexingError: Too many indexers 

In [6]: s.iloc[(3,7)] 
--------------------------------------------------------------------------- 
IndexingError        Traceback (most recent call last) 
........ 

IndexingError: Too many indexers 

И .ix производит странный результат:

In [7]: s.ix[(3,7)] 
Out[7]: 3 

Теперь я понимаю, что вы можете» t даже сделать это с необработанным питоном list:

In [27]: 
x = list(range(0,10)) 
x[(3,7)] 

--------------------------------------------------------------------------- 
TypeError         Traceback (most recent call last) 
<ipython-input-27-cefdde088328> in <module>() 
     1 x = list(range(0,10)) 
----> 2 x[(3,7)] 

TypeError: list indices must be integers or slices, not tuple 

Чтобы получить набор конкретных индексов от list, вам необходимо использовать понимание, as explained here.

Но, с другой стороны, с помощью tuple для выбора строк из pandas DataFrame, похоже, отлично работает для всех трех методов индексирования. Вот пример с методом .loc:

In [8]: 
from pandas import DataFrame 
df = DataFrame({"x" : np.arange(0,10)}) 

In [9]: 
df.loc[(3,7),"x"] 

Out[9]: 
3 3 
7 7 
Name: x, dtype: int64 

Мои три вопроса являются:

  • Почему не в Series индексаторах принять tuple? Казалось бы,
    естественным для использования tuple, так как набор желаемых индексов является
    неизменяемым, одноразовым параметром. Является ли это исключительно для целей , имитирующих интерфейс list?
  • Каково объяснение странного результата Series.ix?
  • Почему несоответствие между Series и DataFrame по этому вопросу?

ответ

2

Я думаю, что ответ на первый вопрос заключается в том, что tuples используются для поиска в MultiIndex. Я не думаю, что есть хорошие ответы на два вторых вопроса, за исключением того, что вы указали ошибку и несоответствие, соответственно, в коде (это не так сложно сделать :)). Так что Series жалуется, потому что у вас нет MultiIndex или, в более общем плане, длина кортежа больше, чем количество уровней в вашем индексе. DataFrame должен, вероятно, реагировать таким же образом, но это не так. Я думаю, что самый безопасный способ - зарезервировать tuples для MultiIndex и использовать списки/массивы/серии для индексирования нескольких строк. В качестве побочного примечания вы должны использовать список/массив кортежей для выбора нескольких строк в MultiIndex.

2

Трудно ответить на этот вопрос на систематической основе, так что я буду просто ответить список-стиль:

  1. Я думаю, больше вопрос может быть, что именно вы пытаетесь сделать, но не в состоянии? То есть почему вы хотите использовать () вместо [], когда [] является стандартным способом?
  2. Ваш первый вопрос действительно о том, почему синтаксис является определенным способом, и это почти нереальный вопрос для ответа, не углубляясь в историю не только панд, но и numpy. В любом случае простой ответ @ JoeCondron правильный: кортежи для мультииндексов, а списки предназначены для расширенной индексации (он же «причудливая индексация»). Я считаю, что причудливое индексирование было отменено непосредственно из numpy, а мультииндексы были добавлены пандами.
  3. Для вашего последнего вопроса, я думаю, это несогласованность, но Series и DataFrames - это не то же самое, поэтому их поведение не может быть на 100% последовательным. В частности, индексирование DataFrame требует дополнительных механизмов для различения строк и столбцов, тогда как серия должна беспокоиться только о строках.
  4. Чтобы ответить на ваш вопрос в очень общем смысле, я думаю, что вы показываете здесь, что при использовании нестандартного синтаксиса может, тем не менее, работает так, как вы хотите, но это может быть не так. Поэтому я не думаю, что справедливо сказать, что df.loc работал здесь и s.loc не сделал. Не было гарантировано работать здесь (согласно документации), но случилось с df.loc. Кроме того, вполне возможно, что df.loc перестанет работать так, как в будущей версии.
  5. Если вы найдете пример loc/iloc/ix, который не работает, как показано в документации, это должно указываться и сообщаться как ошибка. Я не верю, что в эту категорию попало какое-либо из перечисленных выше, но я, конечно, ошибаюсь.
+0

Согласовано на всех. Чтобы ответить на ваш первый вопрос, все, что я пытаюсь сделать, это использовать синтаксис, который, я думаю, был бы естественным. Вы могли бы подумать, что определенный набор номеров индексов будет таким же неизменным, как и все, и «кортеж» будет иметь смысл. Это не конец света, что я не могу использовать «кортеж», и я особо не зацикливаюсь на этом. В конце концов, неспособность сделать это не помешала мне так сильно, как вызвать мое любопытство. –

+0

Отличный ответ. Я бы сказал, что 's.ix [(3, 7)]' return '3' является ошибкой. Я не могу представить, как это может быть предполагаемое поведение, и я думаю, что это пример того, как неожиданные исходные данные когда-то плохо обрабатываются в Pandas. – JoeCondron

+0

@JoeCondron да, хороший пункт! полностью согласен с вами в этом. – JohnE

Смежные вопросы