2015-12-14 34 views
5

我注意到在Pandas中对DataFrame进行子集化时,locix之间存在奇怪的差异。loc和ix之间的意外差异

import pandas as pd 

# Create a dataframe 
df = pd.DataFrame({'id':[10,9,5,6,8], 'x1':[10.0,12.3,13.4,11.9,7.6], 'x2':['a','a','b','c','c']}) 
df.set_index('id', inplace=True) 

df 
     x1 x2 
id   
10 10.0 a 
9 12.3 a 
5 13.4 b 
6 11.9 c 
8 7.6 c 


df.loc[[10, 9, 7]] # 7 does not exist in the index so a NaN row is returned 
df.loc[[7]] # KeyError: 'None of [[7]] are in the [index]' 
df.ix[[7]] # 7 does not exist in the index so a NaN row is returned 

为什么df.loc[[7]]抛出一个错误,而df.ix[[7]]返回一行与南?这是一个错误?如果没有,为什么locix这样设计?

(注意:我使用的是熊猫0.17.1上的Python 3.5.1)

+0

决定这是最有可能的错误。提交报告[这里](https://github.com/pydata/pandas/issues/11840) – Ben

回答

2

由于@shanmuga说,这是(至少对于loc预期和记录的行为,而不是一个错误

由标签loc /选择的文件,给出了这一规则(http://pandas.pydata.org/pandas-docs/stable/indexing.html#selection-by-label):

至少1你问标签的,必须在索引或KeyError异常会被抚养!

这意味着使用loc与单个标签(如df.loc[[7]])如果此标签不是在索引中,但标签的列表使用它时(如df.loc[[7,8,9]])将不会提高,如果一个错误会引发错误至少有一个标签在索引中。


对于ix我不太确定,而且我没有清楚地记录。但无论如何,ix更宽容,并有很多边缘情况(回退到整数位置等),而且是一个兔子洞。但一般而言,ix将始终返回使用提供的标签进行索引的结果(因此不会检查标签是否位于索引中,如loc一样),除非它回退到整数位置索引。
在大多数情况下,建议使用loc/iloc

+0

有什么让人困惑的是,'df.loc [[7,8,9]]'实际上会返回id = 7的行,但'df.loc [[7]]'不会。我希望他们要么都出错,要么'df.loc [[7,8,9]]'不返回id = 7的行。尽管如此,我很高兴知道这不是一个错误。谢谢你的帮助。 – Ben

1

我认为这种行为是有意的,不是一个错误。
虽然我找不到任何官方文件,但我发现jreback于2014年3月21日issue on GitHub表示此意见。

IX可以很巧妙地给出错误的结果(使用说偶数索引)

你可以使用任何你想要的功能; IX仍然存在,但它不提供保证LOC提供,即它不会解释一个数字作为位置


至于为什么它被设计成
正如上文docs

.ix支持基于混合整数和标签的访问。它主要是基于标签的,但是会回退到整数位置访问,除非相应的轴是整数类型。

在我看来,提出KeyError将是不明确的,因为它是否来自索引或整数位置。相反ix回报NaN时提供的列表

+0

但是,为什么'df.loc [[7]]'返回一个错误,'df.loc [[10, 9,7]]'返回一个三行的数据框?那是什么目的? – Ben

+0

'.loc'提供了一个担保,该值存在于DataFrame索引中。但'.ix'不能保证这一点(它会在返回到整数位置之前检查两个索引)。在这种情况下(恕我直言)更好地给予'NaN'而不是提高一个关键错误是更好的。 – shanmuga

+0

同样,如果'.loc'提供担保,'df.loc [[10,9,7]]'返回三行(即包含一个id = 7,如果没有这样的id存在) – Ben