天天看點

Python 資料分析——Pandas 下标存取

作者:昌華量化
Python 資料分析——Pandas 下标存取

Series和DataFrame提供了豐富的下标存取方法,除了直接使用[]運算符之外,還可以使用.loc[]、.iloc[]、.at[]、.iat[]和.ix[]等存取器存取其中的元素。

下面的表1總結了DataFrame對象的各種存取方法:

表1 DataFrame對象的各種存取方法

方法 說明
[col_label] 以單個标簽作為下标,擷取與标簽對應的列,傳回Series對象
[col_labels] 以标簽清單作為下标,擷取對應的多個列,傳回DataFrame對象
[row_slice] 整數切片或标簽切片,得到指定範圍之内的行
[row_bool_array] 選擇布爾數組中True對應的行
.get(col_label, default) 與字典的get()方法的用法相同
.at[index_label, col_label] 選擇行标簽和列标簽對應的值,傳回單個元素
.iat[index, col] 選擇行編号和列編号對應的值,傳回單個元素
.loc[index, col] 通過單個标簽值、标簽清單、标簽數組、布爾數組、标簽切片等選擇指定行與列上的資料
.iloc[index, col] 通過單個整數值、整數清單、整數數組、布爾數組、整數切片選擇指定行與列上的資料
.ix[index, col] 同時擁有.loc[]和.iloc[]的功能,既可以使用标簽下标也可以使用整數下标
.lookup(row_labels, col_labels) 選擇行标簽清單與列标簽清單中每對标簽對應的元素值
.get_value(row_label, col_label) 與.at[]的功能類似,不過速度更快
.query() 通過表達式選擇滿足條件的行
.head() 擷取頭部N行資料
.tail() 擷取尾部N行資料
np.random.seed(42)
df = pd.DataFrame(np.random.randint(0, 10, (5, 3)), 
index=["r1", "r2", "r3", "r4", "r5"], 
columns=["c1", "c2", "c3"])           

一、[]操作符

通過[]操作符對DataFrame對象進行存取時,支援以下5種下标對象:

·單個索引标簽:擷取标簽對應的列,傳回一個Series對象。

·多個索引标簽:擷取以清單、數組(注意不能是元組)表示的多個标簽對應的列,傳回一個DataFrame對象。

·整數切片:以整數下标擷取切片對應的行。

·标簽切片:當使用标簽作為切片時包含終值。

·布爾數組:擷取數組中True對應的行。

·布爾DataFrame:将DataFrame對象中False對應的元素設定為NaN。

下面顯示整數切片和标簽切片的結果,注意标簽切片包含終值"r4":

Python 資料分析——Pandas 下标存取

df.c1 > 4是一個布爾序列,是以df[df.c1 > 4]獲得該序列中True對應的行。df > 2是一個布爾DataFrame對象,df[df > 2]将其中False對應的元素置換為NaN:

Python 資料分析——Pandas 下标存取

二、.loc[]和.iloc[]存取器

.loc[]的下标對象是一個元組,其中的兩個元素分别與DataFrame的兩個軸相對應。若下标不是元組,則該下标對應第0軸,:對應第1軸。每個軸的下标對象都支援單個标簽、标簽清單、标簽切片以及布爾數組。

df.loc["r2"]獲得"r2"對應的行,它傳回一個Series對象。df.loc["r2", "c2"]獲得"r2"行"c2"列的元素,它傳回單個元素值。

Python 資料分析——Pandas 下标存取

df.loc[["r2", "r3"]]獲得"r2"和"r3"對應的行。df.loc[["r2","r3"],["c1","c2"]]則獲得"r2"和"r3"行、"c1"和"c2"列上的資料,所得到的資料都是新的DataFrame對象。

Python 資料分析——Pandas 下标存取

在下面的程式中,第0軸的下标分别為标簽切片和布爾數序列:

Python 資料分析——Pandas 下标存取

.iloc[]和loc[]類似,不過它使用整數下标:

Python 資料分析——Pandas 下标存取

此外.ix[]的存取器可以混用标簽和位置下标,例如:

Python 資料分析——Pandas 下标存取

如果DataFrame對象有整數索引,則應該使用.loc[]和.iloc[]以避免混淆。

三、擷取單個值

.at[]和.iat[]分别使用标簽和整數下标擷取單個值,此外get_value()與.at[]類似,不過其執行速度要快一些:

Python 資料分析——Pandas 下标存取

當.loc[]的下标對象是兩個标簽清單時,所獲得的是這兩個清單形成的網格上的元素,這與NumPy的數組下标操作不一樣。如果希望擷取兩個清單中每對标簽所對應的元素,可以使用lookup(),它傳回一個包含指定元素的數組:

df.lookup(["r2", "r4", "r3"], ["c1", "c2", "c1"])
array([4, 3, 2])           

四、多級标簽的存取

.loc[]和.at[]的下标可以指定多級索引中每級索引上的标簽。這時多級索引軸對應的下标是一個下标元組,該元組中的每個元素與索引中的每級索引對應。若下标不是元組,則将其轉換為長度為1的元組,若元組的長度比索引的層數少,則在其後面補slice(None)。

soil_df = pd.read_csv("data/Soils-simple.csv", index_col=[0, 1], parse_dates=["Date"])           

在下面的例子中,"10-30"為第0軸的标簽,根據前面的規則,将其轉換為("10-30", slice(None)),即選擇第0級中"10-30"對應的行:

Python 資料分析——Pandas 下标存取

如果需要選擇第1級中"Top"對應的行,則需要把slice(None)作為第0級的下标。由于Python中隻有直接在[]中才能使用以:分隔的切片文法,是以這裡使用np.s_對象建立第0軸對應的下标:(slice(None), "Top")。

Python 資料分析——Pandas 下标存取

五、query()方法

當需要根據一定的條件對行進行過濾時,通常可以先建立一個布爾數組,使用該數組擷取True對應的行,例如下面的程式獲得pH值大于5、Ca含量小于11%的行。由于Python中無法自定義not、and和or等關鍵字的行為,是以需要改用~、&、|等位運算符。然而這些運算符的優先級比比較運算符要高,是以需要用括号将比較運算括起來:

soil_df[(soil_df.pH > 5) & (soil_df.Ca < 11)]

使用query()可以簡化上述程式:

Python 資料分析——Pandas 下标存取

query()的參數是一個運算表達式字元串。其中可以使用not、and和or等關鍵字進行向量布爾運算,表達式中的變量名表示與其對應的列。如果希望在表達式中使用其他全局或局域變量的值,可以在變量名之前添加@,例如:

pH_low = 5
Ca_hi = 11
print soil_df.query("pH > @pH_low and Ca < @Ca_hi")