Python loc和ix之间的意外差异
我注意到在Pandas中子集数据帧时,Python loc和ix之间的意外差异,python,pandas,Python,Pandas,我注意到在Pandas中子集数据帧时,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
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]]
返回带有NaN的行时抛出错误?这是虫子吗?如果不是,为什么loc
和ix
是这样设计的
(注意,我在Python 3.5.1上使用的是Pandas 0.17.1)我认为这种行为是故意的,而不是bug。
虽然我找不到任何官方文件,但我在2014年3月21日找到了jreback的一条评论,指出了这一点 ix可以非常巧妙地给出错误的结果(使用偶数索引) 你可以使用任何你想要的功能;ix仍然存在,但它没有提供loc提供的保证,即它不会将数字解释为位置
至于为什么设计成这样
如中所述 .ix支持混合整数和基于标签的访问。它主要基于标签,但会退回到整数位置访问,除非相应的轴是整数类型
在我看来,提出一个
KeyError
是不明确的,因为它是来自索引还是整数位置。相反,ix
在给定列表时返回NaN
,正如@shanmuga所说,这是(至少对于loc
)预期和记录的行为,而不是bug
loc
/selection by label上的文档提供了有关此()的规则:
您要求的标签中至少有1个必须在索引中,否则将引发KeyError
这意味着如果此标签不在索引中,则将loc
与单个标签(例如df.loc[[7]]]
)一起使用将产生错误,但当将其与标签列表(例如df.loc[[7,8,9]]
一起使用时,如果这些标签中至少有一个在索引中,则不会产生错误
对于
ix
我不太确定,我认为这没有明确的文档记录。但在任何情况下,ix
更为宽松,有很多边缘情况(退回到整数位置等),这是一个兔子洞。但一般来说,ix
将始终返回使用提供的标签索引的结果(因此不会像loc
那样检查标签是否在索引中),除非返回到整数位置索引。在大多数情况下,建议使用
loc
/iloc
,但为什么df.loc[[7]]
会返回错误,而df.loc[[10,9,7]]
会返回三行数据帧?这样做的目的是什么?.loc
保证数据帧索引中存在这些值。但是.ix
并不能保证这一点(它会在返回到整数位置之前检查两个索引)。在这种情况下(IMHO)最好给出NaN
而不是提出一个关键错误。同样,如果提供了您提到的保证,为什么df.loc[[10,9,7]]
会返回三行(即当不存在这样的id时,包括id=7的一行)?我同意,这是不一致的行为。我找不到任何文档来解释这一点。我认为这很可能是一个bug。提交了一份报告。令人困惑的是,df.loc[[7,8,9]]
实际上返回了id=7的一行,但df.loc[[7]]
没有返回。我希望它们要么都出错,要么对于df.loc[[7,8,9]]
不返回id=7的行。尽管如此,我很高兴知道这不是一个bug。谢谢你的帮助。