pandas的索引應統一用 loc & iloc

numpy的axis、索引已經夠亂了

但是pandas的索引,更亂!

先來一段程序壓壓驚

import numpy as npnimport pandas as pdnndf = pd.DataFrame({ A : 1.,n B : pd.Timestamp(20130102),n C : pd.Series(1,index=list(abcd),dtype=float32),n D : np.array([3] * 4,dtype=int32),n E : pd.Categorical(["test","train","test","train"]),n F : foo })nn A B C D E Fna 1.0 2013-01-02 1.0 3 test foonb 1.0 2013-01-02 1.0 3 train foonc 1.0 2013-01-02 1.0 3 test foond 1.0 2013-01-02 1.0 3 train foon

開始索引了

print(df[A])nprint(df[[A,C]]) # print(df[A,C]) 報錯nprint(df[1:3]) # 取第一和第二行nprint(df[a:c]) # 取a,b,c三行,呵呵nprint(df[[1,3]]) # 取第一列和第三列n

下面是對應的輸出

a 1.0nb 1.0nc 1.0nd 1.0nName: A, dtype: float64nnn A Cna 1.0 1.0nb 1.0 1.0nc 1.0 1.0nd 1.0 1.0nnn A B C D E Fnb 1.0 2013-01-02 1.0 3 train foonc 1.0 2013-01-02 1.0 3 test foonnn A B C D E Fna 1.0 2013-01-02 1.0 3 test foonb 1.0 2013-01-02 1.0 3 train foonc 1.0 2013-01-02 1.0 3 test foonnn B Dna 2013-01-02 3nb 2013-01-02 3nc 2013-01-02 3nd 2013-01-02 3n

是不是夠亂了,如果index本身就是int的話,那簡直會要人親命...比如說,你用了個pd.read_sql()函數來從資料庫讀入數據,就會默認建int型的行標籤。那df[1:3]就會選1,2,3共3行...

下面使用loc 和 iloc

print(df.loc[[a,c],[A,C]])nprint(df.iloc[[0,1,2],[0,1,2]])nprint(df.iloc[0:3,0:3])nprint(df.iloc[0,0],type(df.iloc[0,0]))nprint(df.iat[0,0],type(df.iat[0,0]))n

對應的輸出

A Cna 1.0 1.0nc 1.0 1.0nnn A B Cna 1.0 2013-01-02 1.0nb 1.0 2013-01-02 1.0nc 1.0 2013-01-02 1.0nnn A B Cna 1.0 2013-01-02 1.0nb 1.0 2013-01-02 1.0nc 1.0 2013-01-02 1.0nnn1.0 <class numpy.float64>nnn1.0 <class numpy.float64>n

其實還有一個ix來取索引...但是也很難用...

ix / loc 可以通過行號和行標籤進行索引,比如 df.loc[a] , df.loc[1], df.ix[a] , df.ix[1]

而iloc只能通過行號索引 , df.iloc[0] 是對的, 而df.iloc[a] 是錯誤的

loc 和 ix 大部分時候行為都差不多, 但是當假如某個行的索引標籤就是一個 INT 比如 1 的時候, loc 優先將 df.loc[1] 理解為行標籤為 1 的索引, 而 df.ix[1] 優先將其理解為 行號為 1 的索引(就是第二行)。

也就是此時df[1:3]就會選1,2,3共3行...df.loc[1:3]選擇1,2,3共3行...df.iloc[1:3]選擇1,2,共2行...好累啊,感覺不會再...

引用一個知乎上的回答

zhihu.com/question/4736

為了避免不小心犯錯誤, 建議:

1.當用行號索引的時候, 盡量用 iloc 來進行索引;

2. 而用標籤索引的時候用 loc ,

3. ix 就別用了


總結:

  • pandas的索引應該只用loc和iloc
  • 根據標籤名和列名選取更方便時用loc,即使標籤和列為int型,也是根據名字選
  • 根據標籤行號和列號選取更方便用iloc,即使標籤和列為int型,也是根據第幾行第幾列來選
  • 統一寫成 (i)loc[ indexs, colunms]的形式,indexs和columns為 [x,x,x] 或者x : x的形式。indexs和columns都不要省略,即使全選也要寫:
  • 只取標量可以用at和iat提高效率

用loc和iloc,不糾結!


推薦閱讀:

數據分析師職位分析
如何看待yandex開源clickhouse這個列式文檔資料庫?
諸葛io,面向數據智能時代的大數據實踐(下)
歐先生(R語言)玩轉Tensorflow(三)

TAG:Python | 数据分析 | 数据挖掘 |