2015-12-14 37 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