DataFrame的iloc,ix和loc這三種切片方法有何不同嗎?
之前看過一些官方文檔,但還是無法理解這三者之間的區別。
例如,假設我們要獲取DataFrame
的前五行。這三者內部是如何實現的?求解釋!
df.loc[:5]
df.ix[:5]
df.iloc[:5]
最佳回答
iloc
基於整數定位。因此,無論您的行標簽是什麽,您始終可以例如通過執行以下操作獲得第一行
df.iloc[0]
或最後五行
df.iloc[-5:]
您也可以在列上使用它。這將檢索第三列:
df.iloc[:, 2] # the : in the first position indicates all rows
您可以將它們結合起來以獲得行和列的交集:
df.iloc[:3, :3] # The upper-left 3 X 3 entries (assuming df has 3+ rows and columns)
另一方麵,.loc
使用命名索引。給定一個帶有字符串作為行和列標簽的DataFrame:
df = pd.DataFrame(index=['a', 'b', 'c'], columns=['time', 'date', 'name'])
然後我們可以得到第一行
df.loc['a'] # equivalent to df.iloc[0]
和'date'
列的後兩行
df.loc['b':, 'date'] # equivalent to df.iloc[1:, 1]
可能值得指出的是,DataFrame
的默認行和列索引是從0開始的整數。如果您有非數字索引,例如字符串或日期時間,則df.loc[:5]
會引發錯誤。
另外,您可以使用DataFrame的__getitem__
進行列檢索:
df['time'] # equivalent to df.loc[:, 'time']
如果您要混合使用位置索引和命名索引,比如說使用行上的名稱和列上的位置進行索引。這通常需要用.ix
:
df.ix[:2, 'time'] # the first two rows of the 'time' column
另外值得一提的是,您也可以將布爾向量傳遞給loc
方法。例如:
b = [True, False, True]
df.loc[b]
將返回df
的第一行和第三行。這等效於df[b]
進行選擇,但也可以用於通過布爾向量進行內容設置:
df.loc[b, 'name'] = 'Mary', 'John'
次佳回答
.ix已棄用且含糊不清,切勿使用
由於不建議使用.ix
,因此我們僅關注.loc
和.iloc
之間的差異。
在討論差異之前,重要的是要了解DataFrame的這個特點:具有用於幫助標識每個列和每個索引的標簽。讓我們看一個示例DataFrame:
df = pd.DataFrame({'age':[30, 2, 12, 4, 32, 33, 69],
'color':['blue', 'green', 'red', 'white', 'gray', 'black', 'red'],
'food':['Steak', 'Lamb', 'Mango', 'Apple', 'Cheese', 'Melon', 'Beans'],
'height':[165, 70, 120, 80, 180, 172, 150],
'score':[4.6, 8.3, 9.0, 3.3, 1.8, 9.5, 2.2],
'state':['NY', 'TX', 'FL', 'AL', 'AK', 'TX', 'TX']
},
index=['Jane', 'Nick', 'Aaron', 'Penelope', 'Dean', 'Christina', 'Cornelia'])
所有粗體字均為標簽。列使用標簽age
,color
,food
,height
,score
和state
列。索引使用的是標簽Jane
,Nick
,Aaron
,Penelope
,Dean
,Christina
,Cornelia
。
選擇DataFrame中特定行的主要方法是使用.loc
和.iloc
索引器。此外,每個索引器都使用緊跟其名稱的一組方括號來進行選擇。這些索引器也都可以用於選擇列,這裏為了簡便起見,隻探討行的選擇。
.loc僅通過標簽選擇數據
我們將首先討論.loc
索引器,該索引器僅通過索引或列標簽選擇數據。在示例DataFrame中,我們提供了有意義的名稱作為索引值。許多DataFrame都沒有任何有意義的名稱,而是默認為0到n-1之間的整數,其中n是DataFrame的長度。
您可以為.loc
使用三種不同的輸入
- 一個字符串
- 字符串列表
- 使用字符串作為起始值和終止值的切片符號
用帶字符串的.loc選擇單行
要選擇單行數據,請將索引標簽放在.loc
之後的括號內。
df.loc['Penelope']
這將數據行作為Series(序列)返回
age 4
color white
food Apple
height 80
score 3.3
state AL
Name: Penelope, dtype: object
使用.loc與多個字符串列表選擇多行
df.loc[['Cornelia', 'Jane', 'Dean']]
這將返回一個DataFrame,其中的數據行按列表中指定的順序排列:
使用帶有切片符號的.loc選擇多行
切片符號由“開始”,“停止”和“步長”三個值定義。按標簽切片時, Pandas 在返回值中包含停止值。以下是從Aaron(亞倫)到Dean(迪恩(含))的片段。它的步長未明確定義,但默認為1。
df.loc['Aaron':'Dean']
可以采用與Python列表相同的方式獲取複雜的切片。
.iloc僅按整數位置選擇數據
DataFrame中數據的每一行和每一列都有一個定義它的整數位置。這是輸出中直觀顯示的標簽的補充。整數位置是以左上角為原點(0)開始的行或列的數量。
您可以為.iloc
使用三種不同的輸入
- 一個整數
- 整數列表
- 使用整數作為起始值和終止值的切片符號
用帶整數的.iloc選擇單行
df.iloc[4]
這將返回第5行(整數位置4)Series(序列)
age 32
color gray
food Cheese
height 180
score 1.8
state AK
Name: Dean, dtype: object
用.iloc選擇帶有整數列表的多行
df.iloc[[2, -2]]
這將返回第三行和倒數第二行的DataFrame:
使用帶切片符號的.iloc選擇多行
df.iloc[:5:3] # 從第0行開始到第5行,步長為3
使用.loc和.iloc同時選擇行和列
.loc和.iloc
的一項出色功能是可以同時選擇行和列。我們隻需要用逗號分隔行和列選擇即可。
例如,我們可以選擇Jane行和Dean行,它們的高度,得分和狀態列如下:
df.loc[['Jane', 'Dean'], 'height':]
上麵的示例對行使用標簽列表,對列使用切片符號
也可以隻使用整數對.iloc
進行類似的操作。
df.iloc[[1,4], 2]
Nick Lamb
Dean Cheese
Name: food, dtype: object
用標簽和整數位置同時選擇
.ix
用於同時使用標簽和整數位置進行選擇,這雖然有用,但有時會造成混淆和歧義,但值得慶幸的是它已被棄用。如果您需要混合使用標簽和整數位置進行選擇,則必須同時選擇標簽或整數位置。
例如,如果我們要選擇Nick
行和Cornelia
行以及第2列和第4列,則可以使用.loc
,方法是將整數轉換為帶有以下內容的標簽:
col_names = df.columns[[2, 4]]
df.loc[['Nick', 'Cornelia'], col_names]
或者,可以使用get_loc
索引方法將索引標簽轉換為整數。
labels = ['Nick', 'Cornelia']
index_ints = [df.index.get_loc(label) for label in labels]
df.iloc[index_ints, [2, 4]]
布爾選擇
.loc索引器還可以進行布爾選擇。例如,如果我們有興趣查找年齡在30歲以上的所有行,並僅返回food
和score
列,則可以執行以下操作:
df.loc[df['age'] > 30, ['food', 'score']]
您可以使用.iloc實現類似的功能
,但不能將其傳遞為布爾Series(係列),而必須將boolean Series轉換為numpy數組,如下所示:
df.iloc[(df['age'] > 30).values, [2, 4]]
選擇所有行[即做列選擇]
可以將.loc和.iloc
用於僅列選擇。您可以使用如下冒號來選擇所有行:
df.loc[:, 'color':'score':2]
索引運算符[]
也可以選擇行和列,但不能同時選擇。
大多數人都熟悉DataFrame索引運算符的主要目的,即選擇列。字符串選擇單個列作為係列,而字符串列表選擇多個列作為DataFrame。
df['food']
Jane Steak
Nick Lamb
Aaron Mango
Penelope Apple
Dean Cheese
Christina Melon
Cornelia Beans
Name: food, dtype: object
使用列表選擇多個列
df[['food', 'score']]
人們所不熟悉的是,當使用切片符號時,選擇是通過行標簽或整數位置進行的。這非常令人困惑,我幾乎從未使用過,但是確實可以使用。
df['Penelope':'Christina'] # slice rows by label
df[2:6:2] # slice rows by integer location,第3個數字是步長
注意:單獨的索引運算符無法同時選擇行和列。
df[3:5, 'color']
TypeError: unhashable type: 'slice'
參考資料