pandas之loc iloc ix
首先,介紹這三種方法的概述:
loc: loc?gets rows (or columns) with particular?labels?from the index. loc從索引中獲取具有特定標(biāo)簽的行(或列)。這里的關(guān)鍵是:標(biāo)簽。標(biāo)簽的理解就是name名字。
iloc: gets rows (or columns) at particular?positions?in the index (so it only takes integers).?iloc在索引中的特定位置獲取行(或列)(因此它只接受整數(shù))。這里的關(guān)鍵是:位置。位置的理解就是排第幾個(gè)。
ix:?usually tries to behave like?loc?but falls back to behaving like?iloc?if a label is not present in the index.?ix通常會(huì)嘗試像loc一樣行為,但如果索引中不存在標(biāo)簽,則會(huì)退回到像iloc一樣的行為。
1.loc
其實(shí),對(duì)于loc始終堅(jiān)持一個(gè)原則:loc是基于label進(jìn)行索引的!
import pandas as pd df1 = pd.DataFrame(data= [[1, 2, 3],[4, 5, 6], [7, 8, 9]], index=[0, 1, 2], columns=['a','b','c']) df2 = pd.DataFrame(data= [[1, 2, 3],[4, 5, 6], [7, 8, 9]], index=['e', 'f', 'g'], columns=['a','b','c']) print(df1) print(df2) ''' df1:a b c 0 1 2 3 1 4 5 6 2 7 8 9 df2:a b c e 1 2 3 f 4 5 6 g 7 8 9 '''# loc索引行,label是整型數(shù)字 print(df1.loc[0]) ''' a 1 b 2 c 3 Name: 0, dtype: int64 '''# loc索引行,label是字符型 print(df2.loc['e']) ''' a 1 b 2 c 3 Name: 0, dtype: int64 '''# 如果對(duì)df2這么寫(xiě):df2.loc[0]會(huì)報(bào)錯(cuò),因?yàn)閘oc索引的是label,顯然在df2的行的名字中沒(méi)有叫0的。 print(df2.loc[0]) ''' TypeError: cannot do slice indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [0] of <class 'int'> '''# loc索引多行數(shù)據(jù) print(df1.loc[1:]) '''a b c 1 4 5 6 2 7 8 9 '''# loc索引多列數(shù)據(jù) print(df1.loc[:,['a', 'b']]) '''a b 0 1 2 1 4 5 2 7 8 '''
# df1.loc[:,0:2]這么寫(xiě)報(bào)錯(cuò), 因?yàn)閘oc索引的是label,顯然在df1的列的名字中沒(méi)有叫0,1和2的。 print(df1.loc[:,0:2]) ''' TypeError: cannot do slice indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [0] of <class 'int'> '''# locs索引某些行某些列 print(df1.loc[0:2, ['a', 'b']]) '''a b 0 1 2 1 4 5 2 7 8 '''
2.iloc
對(duì)于iloc始終也堅(jiān)持一個(gè)原則:iloc是基于position進(jìn)行索引的!
import pandas as pd df1 = pd.DataFrame(data= [[1, 2, 3],[4, 5, 6], [7, 8, 9]], index=[0, 1, 2], columns=['a','b','c']) df2 = pd.DataFrame(data= [[1, 2, 3],[4, 5, 6], [7, 8, 9]], index=['e', 'f', 'g'], columns=['a','b','c']) print(df1) print(df2) ''' df1:a b c 0 1 2 3 1 4 5 6 2 7 8 9 df2:a b c e 1 2 3 f 4 5 6 g 7 8 9 '''# iloc索引行,label是整型數(shù)字 print(df1.iloc[0]) ''' a 1 b 2 c 3 Name: 0, dtype: int64 '''# iloc索引行,label是字符型。如果按照l(shuí)oc的寫(xiě)法來(lái)寫(xiě)應(yīng)該是:df2.iloc['e'],顯然這樣報(bào)錯(cuò),因?yàn)閕loc不認(rèn)識(shí)label,它是基于位置的。 print(df2.iloc['e']) ''' TypeError: cannot do positional indexing on <class 'pandas.core.indexes.base.Index'> with these indexers [e] of <class 'str'> '''
# iloc索引行,label是字符型。正確的寫(xiě)法應(yīng)該如下: # 也就說(shuō),不論index是什么類(lèi)型的,iloc只能寫(xiě)位置,也就是整型數(shù)字。 print(df2.iloc[0]) ''' a 1 b 2 c 3 Name: e, dtype: int64 '''# iloc索引多行數(shù)據(jù) print(df1.iloc[1:]) '''a b c 1 4 5 6 2 7 8 9 '''# iloc索引多列數(shù)據(jù) # 如果如下寫(xiě)法,報(bào)錯(cuò)。 print(df1.iloc[:,['a', 'b']]) ''' TypeError: cannot perform reduce with flexible type '''
# iloc索引多列數(shù)據(jù), 正確寫(xiě)法如下: print(df1.iloc[:,0:2]) '''a b 0 1 2 1 4 5 2 7 8 '''# iloc索引某些行某些列 print(df1.iloc[0:2, 0:1]) '''a 0 1 1 4 '''
3.ix
注:ix的操作比較復(fù)雜,在pandas版本0.20.0及其以后版本中,ix已經(jīng)不被推薦使用,建議采用iloc和loc實(shí)現(xiàn)ix。
(1)如果索引是整數(shù)類(lèi)型,則ix將僅使用基于標(biāo)簽的索引,而不會(huì)回退到基于位置的索引。如果標(biāo)簽不在索引中,則會(huì)引發(fā)錯(cuò)誤。
(2)如果索引不僅包含整數(shù),則給定一個(gè)整數(shù),ix將立即使用基于位置的索引而不是基于標(biāo)簽的索引。但是,如果ix被賦予另一種類(lèi)型(例如字符串),則它可以使用基于標(biāo)簽的索引。
接下來(lái)舉例說(shuō)明這兩個(gè)特點(diǎn):
>>> 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現(xiàn)在我們來(lái)看使用整數(shù)3切片有什么結(jié)果:
在這個(gè)例子中,s.iloc[:3]讀取前3行(因?yàn)閕loc把3看成是位置position),而s.loc[:3]讀取的是前8行(因?yàn)閘oc把3看作是索引的標(biāo)簽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]返回的結(jié)果與s.loc[:3]一樣,這是因?yàn)槿绻鹲eries的索引是整型的話,ix會(huì)首先去尋找索引中的標(biāo)簽3而不是去找位置3。
如果,我們?cè)噲D去找一個(gè)不在索引中的標(biāo)簽,比如說(shuō)是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錯(cuò)誤,這是因?yàn)闃?biāo)簽6并不在索引中。
那么,s.ix[:6]報(bào)錯(cuò)的原因是什么呢?正如我們?cè)趇x的特點(diǎn)1所說(shuō)的那樣,如果索引只有整數(shù)類(lèi)型,那么ix僅使用基于標(biāo)簽的索引,而不會(huì)回退到基于位置的索引。如果標(biāo)簽不在索引中,則會(huì)引發(fā)錯(cuò)誤。
如果我們的索引是一個(gè)混合的類(lèi)型,即不僅僅包括整型,也包括其他類(lèi)型,如字符類(lèi)型。那么,給ix一個(gè)整型數(shù)字,ix會(huì)立即使用iloc操作,而不是報(bào)KeyError錯(cuò)誤。
>>> s2 = pd.Series(np.nan, index=['a','b','c','d','e', 1, 2, 3, 4, 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這個(gè)例子就說(shuō)明了ix特點(diǎn)2。
正如前面所介紹的,ix的使用有些復(fù)雜。如果僅使用位置或者標(biāo)簽進(jìn)行切片,使用iloc或者loc就行了,請(qǐng)避免使用ix。
4.在Dataframe中使用ix實(shí)現(xiàn)復(fù)雜切片
有時(shí)候,在使用Dataframe進(jìn)行切片時(shí),我們想混合使用標(biāo)簽和位置來(lái)對(duì)行和列進(jìn)行切片。那么,應(yīng)該怎么操作呢?
舉例,考慮有下述例子中的Dataframe。我們想得到直到包含標(biāo)簽'c'的行和前4列。
>>> df = pd.DataFrame(np.nan, index=list('abcde'),columns=['x','y','z', 8, 9]) >>> dfx 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可以很好地實(shí)現(xiàn)這個(gè)功能。
我們可以使用標(biāo)簽來(lái)切分行,使用位置來(lái)切分列(請(qǐng)注意:因?yàn)?并不是列的名字,因?yàn)閕x在列上是使用的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的后來(lái)版本中,我們可以使用iloc和其它的一個(gè)方法就可以實(shí)現(xiàn)上述功能:
>>> 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 NaNget_loc()?是得到標(biāo)簽在索引中的位置的方法。請(qǐng)注意,因?yàn)槭褂胕loc切片時(shí)不包括最后1個(gè)點(diǎn),因?yàn)槲覀儽仨毤?。
可以看到,只使用iloc更好用,因?yàn)椴槐乩頃?huì)ix的那2個(gè)“繁瑣”的特點(diǎn)。
參考文獻(xiàn):https://stackoverflow.com/questions/31593201/pandas-iloc-vs-ix-vs-loc-explanation-how-are-they-different
轉(zhuǎn)載于https://blog.csdn.net/anshuai_aw1/article/details/82801435
轉(zhuǎn)載于:https://www.cnblogs.com/RB26DETT/p/11557339.html
總結(jié)
以上是生活随笔為你收集整理的pandas之loc iloc ix的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python数据拼接: pd.conca
- 下一篇: SDNU 1085.爬楼梯再加强版(矩阵