为什么你能在熊猫中做df.loc(False)['value']?

use*_*897 14 python indexing pandas

我没有看到任何关于pandas的文档,解释传递给loc的参数False.任何人都可以解释这种情况下()和[]的不同之处吗?

cs9*_*s95 12

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>

...
Run Code Online (Sandbox Code Playgroud)

等等.传入的值(...)不以任何方式由实例使用.

另一方面,传递给的属性[...]被发送到__getitem__/ __setitem__进行检索/设置.


Uva*_*var 5

正如其他答案已经解释的那样,()大括号调用__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
Run Code Online (Sandbox Code Playgroud)

它返回自己的副本.现在,在do之间传递的参数()是实例化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)
Run Code Online (Sandbox Code Playgroud)

因此,无论您传入什么参数.loc(whatever),都会使用默认值覆盖它.您在调用时会看到类似的行为,默认情况下会调用.iloc这些行为_iLocIndexer(_LocationIndexer),因此也会覆盖此行为axis.

axis会发挥作用吗?答案是:在弃用的.ix方法中.我有一个形状的数据框(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
Run Code Online (Sandbox Code Playgroud)

如果使用简单的标量索引,axis在这个2-D示例中仍然会被忽略,因为该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的调用的参数被忽略.