Я не вижу никакой документации по pandas, объясняя параметр False, переданный в loc. Может ли кто-нибудь объяснить, как() и [] отличаются в этом случае?
Почему вы можете сделать df.loc(False) ['значение'] в pandas?
Ответ 1
df.loc является экземпляром класса _LocIndexer, который является подклассом _NDFrameIndexer.
Когда вы выполняете df.loc(...), кажется, вызывается метод __call__, который безобидно возвращает другой экземпляр сам по себе. Например:
In [641]: df.loc
Out[641]: <pandas.core.indexing._LocIndexer at 0x10eb5f240>
In [642]: df.loc()()()()()()
Out[642]: <pandas.core.indexing._LocIndexer at 0x10eb5fe10>
...
И так далее. Значение, переданное в (...), каким-либо образом не используется экземпляром.
С другой стороны, атрибуты, переданные в [...], отправляются на __getitem__/__setitem__, который выполняет поиск/настройку.
Ответ 2
Как уже объясняют другие ответы, скобки () вызывает метод __call__, который определяется как:
def __call__(self, axis=None):
# we need to return a copy of ourselves
new_self = self.__class__(self.obj, self.name)
new_self.axis = axis
return new_self
Он возвращает копию самого себя. Теперь, что передал аргумент между (), заключается в создании экземпляра члена axis вашей новой копии. Таким образом, это может поставить вопрос о том, почему не имеет значения, какое значение вы передаете в качестве аргумента, результирующий индексатор точно такой же. Ответ на этот вопрос заключается в том, что суперкласс _NDFrameIndexer используется для нескольких дочерних классов.
Для метода .loc, который вызывает класс _LocIndexer, этот член не имеет значения. Класс LocIndexer сам является подклассом _LocationIndexer, который является подклассом _NDFrameIndexer.
Каждый раз, когда axis вызывается _LocationIndexer, он по умолчанию равен нулю, без возможности его указания самостоятельно. Например, я буду ссылаться на одну из функций внутри класса, а другие следуют примеру:
def __getitem__(self, key):
if type(key) is tuple:
key = tuple(com._apply_if_callable(x, self.obj) for x in key)
try:
if self._is_scalar_access(key):
return self._getitem_scalar(key)
except (KeyError, IndexError):
pass
return self._getitem_tuple(key)
else:
key = com._apply_if_callable(key, self.obj)
return self._getitem_axis(key, axis=0)
Итак, независимо от того, какой аргумент вы передаете в .loc(whatever), он будет переопределен значением по умолчанию. Аналогичное поведение вы увидите при вызове .iloc, который вызывает _iLocIndexer(_LocationIndexer) и, таким образом, также по умолчанию отменяет этот axis.
Откуда этот axis входит в игру? Ответ: в устаревшем методе .ix. У меня есть dataframe формы (2187, 5), и теперь определите:
a = df.ix(0)
b= df.ix(1)
c = df.ix(2)
a[0] == b[0] #True
b[0] == c[0] #True
a[0,1] == b[0,1] #False
Если вы используете простое скалярное индексирование, axis по-прежнему игнорируется в этом двухмерном примере, так как метод get возвращается к простому скалярному индексированию на основе целых чисел. Однако a[0,1] имеет форму (2,5) < - он принимает первые две записи вдоль axis=0; b[0,1] имеет форму (2187, 2) < - он принимает первые две записи вдоль axis=1; c[0,1] возвращает ValueError: No axis named 2 for object type <class 'pandas.core.frame.DataFrame'>.
Другими словами:
Вы все равно можете вызвать метод вызов класса _NDFrameIndexer, поскольку он используется в подклассе _IXIndexer. Однако: начиная с 0.20.0 индекс индекса .ix устарел, в пользу более строгих индексов .iloc и .loc. Аргумент передан вызов для .iloc и .loc игнорируется.
Ответ 3
Для любого объекта python () вызывает метод __call__, тогда как [] вызывает метод __getitem__ (если вы не устанавливаете значение, и в этом случае он вызывает __setitem__). Другими словами, () и [] вызывают разные методы, так почему вы ожидаете, что они будут действовать одинаково?