1. 程式人生 > 程式設計 >pandas中ix的使用詳細講解

pandas中ix的使用詳細講解

在上一篇部落格中,我們已經仔細講解了iloc和loc,只是簡單了提到了ix。這是因為相比於前2者,ix更復雜,也更讓人迷惑。

因此,本篇部落格通過例子的解釋試圖來描述清楚ix,尤其是與iloc和loc的聯絡。

首先,再次介紹這三種方法的概述:

  • locgets rows (or columns) with particularlabelsfrom the index. loc從索引中獲取具有特定標籤的行(或列)。
  • ilocgets rows (or columns) at particularpositionsin the index (so it only takes integers).iloc在索引中的特定位置獲取行(或列)(因此它只接受整數)。
  • ixusually tries to behave likelocbut falls back to behaving likeilocif a label is not present in the index.ix通常會嘗試像loc一樣行為,但如果索引中不存在標籤,則會退回到像iloc一樣的行為。(這句話有些繞口,沒關係,關於ix特點,後面會詳細講解)

1 使用ix切分Series

請注意:在pandas版本0.20.0及其以後版本中,ix已經不被推薦使用,建議採用iloc和loc實現ix。這是為什麼呢?這是由於ix的複雜特點可能使ix使用起來有些棘手:

  1. 如果索引是整數型別,則ix將僅使用基於標籤的索引,而不會回退到基於位置的索引。如果標籤不在索引中,則會引發錯誤。
  2. 如果索引不僅包含整數,則給定一個整數,ix將立即使用基於位置的索引而不是基於標籤的索引。但是,如果ix被賦予另一種型別(例如字串),則它可以使用基於標籤的索引。

接下來舉例說明這2個特點。

1.1 特點1舉例

>>> s = pd.Series(np.nan,index=[49,48,47,46,45,1,2,3,4,5])
>>> s
49 NaN
48 NaN
47 NaN
46 NaN
45 NaN
1 NaN
2 NaN
3 NaN
4 NaN
5 NaN

現在我們來看使用整數3切片有什麼結果:

在這個例子中,s.iloc[:3]讀取前3行(因為iloc把3看成是位置position),而s.loc[:3]讀取的是前8行(因為loc把3看作是索引的標籤label)

>>> s.iloc[:3] # slice the first three rows
49 NaN
48 NaN
47 NaN
 
>>> s.loc[:3] # slice up to and including label 3
49 NaN
48 NaN
47 NaN
46 NaN
45 NaN
1 NaN
2 NaN
3 NaN
 
>>> s.ix[:3] # the integer is in the index so s.ix[:3] works like loc
49 NaN
48 NaN
47 NaN
46 NaN
45 NaN
1 NaN
2 NaN
3 NaN

注意:s.ix[:3]返回的結果與s.loc[:3]一樣,這是因為如果series的索引是整型的話,ix會首先去尋找索引中的標籤3而不是去找位置3。

如果,我們試圖去找一個不在索引中的標籤,比如說是6呢?

>>> s.iloc[:6]
49 NaN
48 NaN
47 NaN
46 NaN
45 NaN
1 NaN
 
>>> s.loc[:6]
KeyError: 6
 
>>> s.ix[:6]
KeyError: 6

在上面的例子中,s.iloc[:6]正如我們所期望的,返回了前6行。而,s.loc[:6]返回了KeyError錯誤,這是因為標籤6並不在索引中。

那麼,s.ix[:6]報錯的原因是什麼呢?正如我們在ix的特點1所說的那樣,如果索引只有整數型別,那麼ix僅使用基於標籤的索引,而不會回退到基於位置的索引。如果標籤不在索引中,則會引發錯誤。

1.2 特點2舉例

接著例子1來說,如果我們的索引是一個混合的型別,即不僅僅包括整型,也包括其他型別,如字元型別。那麼,給ix一個整型數字,ix會立即使用iloc操作,而不是報KeyError錯誤。

>>> s2 = pd.Series(np.nan,index=['a','b','c','d','e',5])
>>> s2.index.is_mixed() # index is mix of different types
True
>>> s2.ix[:6] # now behaves like iloc given integer
a NaN
b NaN
c NaN
d NaN
e NaN
1 NaN

注意:在這種情況下,ix也可以接受非整型,這樣就是loc的操作:

>>> s2.ix[:'c'] # behaves like loc given non-integer
a NaN
b NaN
c NaN

這個例子就說明了ix特點2。

正如前面所介紹的,ix的使用有些複雜。如果僅使用位置或者標籤進行切片,使用iloc或者loc就行了,請避免使用ix。

2 在Dataframe中使用ix實現複雜切片

有時候,在使用Dataframe進行切片時,我們想混合使用標籤和位置來對行和列進行切片。那麼,應該怎麼操作呢?

舉例,考慮有下述例子中的Dataframe。我們想得到直到包含標籤'c'的行和前4列。

>>> df = pd.DataFrame(np.nan,index=list('abcde'),columns=['x','y','z',8,9])
>>> df
 x y z 8 9
a NaN NaN NaN NaN NaN
b NaN NaN NaN NaN NaN
c NaN NaN NaN NaN NaN
d NaN NaN NaN NaN NaN
e NaN NaN NaN NaN NaN

在pandas的早期版本(0.20.0)之前,ix可以很好地實現這個功能。

我們可以使用標籤來切分行,使用位置來切分列(請注意:因為4並不是列的名字,因為ix在列上是使用的iloc)。

>>> df.ix[:'c',:4]
 x y z 8
a NaN NaN NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN

在pandas的後來版本中,我們可以使用iloc和其它的一個方法就可以實現上述功能:

>>> df.iloc[:df.index.get_loc('c') + 1,:4]
 x y z 8
a NaN NaN NaN NaN
b NaN NaN NaN NaN
c NaN NaN NaN NaN

get_loc()是得到標籤在索引中的位置的方法。請注意,因為使用iloc切片時不包括最後1個點,因為我們必須加1。

可以看到,只使用iloc更好用,因為不必理會ix的那2個“繁瑣”的特點。

3 參考文獻
https://stackoverflow.com/questions/31593201/pandas-iloc-vs-ix-vs-loc-explanation-how-are-they-different

到此這篇關於pandas中ix的使用詳細講解的文章就介紹到這了,更多相關pandas ix內容請搜尋我們以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援我們!