2017-08-17 41 views

回答

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> 

... 

依此类推。以任何方式不会使用在(...)中传递的值。

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

+0

或通过'__setitem__'分配。 OP没有说明。 –

+0

@MadPhysicist注意,谢谢。 –

+0

通常,可以包含在.loc(...)中的参数是什么? – user1559897

2

对于任何Python对象,()调用__call__方法,而[]调用__getitem__方法(除非要设置的值,在这种情况下,它调用__setitem__)。换句话说,()[]调用不同的方法,那么为什么你会期望它们的行为相同呢?

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 

它返回其自身的副本。现在,在()之间传递的参数是实例化新副本的axis成员。所以,这可能会提出一个问题,即为什么不论你作为参数传递什么值并不重要,所得到的索引器完全相同。这个问题的答案在于超类_NDFrameIndexer用于多个子类。

对于调用_LocIndexer类的.loc方法,此成员无关紧要。 LocIndexer类本身是_LocationIndexer的一个子类,它是_NDFrameIndexer的子类。

每次被_LocationIndexer调用时,默认为0,不可能自己指定它。例如,我会参考的类中的功能之一,与其他人纷纷效仿:

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方法中。我有形状(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仍然忽略了这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将被忽略。

相关问题