資料框和序列結構中都有軸標籤,軸標籤的資訊儲存在Index物件中,軸標籤的最重要的作用是:
- 唯一標識資料,用於定位資料
- 用於資料對齊
- 獲取和設定資料集的子集。
本文重點關注如何對序列(Series)和資料框(DataFrame)進行切片(slice),切塊(dice)、如何獲取和設定子集。
下表列出資料框最基本的操作及其語法:
一,最基本的選擇操作
最基本的選擇都是使用中括號[]來實現,但是隻能實現單個維度的選擇。序列(Series)最基本的選擇是使用行標籤來選擇一個標量值,資料框(DataFrame)最基本的選擇是使用列名獲得一個序列。對於序列來說,如果行索引是整數,那麼軸標籤就是整數;對於資料框而言,列的標籤通常都是文字型別。
建立一個資料框,用於資料演示:
df = pd.DataFrame(np.random.randn(8, 4), columns=['A', 'B', 'C', 'D'])
從資料框中獲取A列的資料:
>>> df["A"] 0 -0.053212 1 0.053226 2 0.768993 3 -0.319555 4 0.671913 5 -1.021473 6 1.304257 7 1.215003 Name: A, dtype: float64
從資料框中選擇多個列的資料:
df[["A","B"]]
資料框的一列是一個序列,從序列中獲得一個標量值:
>>> s=df["A"] >>> s[0] -0.05321219353405595
從序列中選擇多行的資料:
s[[0,1]]
二,使用loc 和 iloc來選擇資料
索引的選擇主要是基於標籤的選擇和基於位置的選擇,對於索引來說,位置序號預設從0開始,到length(index)-1 結束。
對於資料框而言,如果沒有填寫row_indexer 或 column_indexer,那麼表示所有的row或column。在row_indexer和column_indexer中,可以使用連續的標籤,比方說,0:4,表示從0到4的一個range,即0、1、2、3,注意不包含4。
1,基於標籤的選擇
.loc 屬性用於基於軸標籤選擇特定的軸,df是資料框結構:
- 單個標籤:df.loc["row"], df.loc["row","col"]
- 多個離散的標籤:df.loc[["row1","row2","row3"]],df.loc[["row1","row2","row3"],["col1","col2"]]
- 連續的標籤:df.loc["row0":"row3"],df.loc["row0":"row3","col0":"col3"]
- 布林掩碼陣列,對於資料框,所有的行構成一個序列,每行都對應一個掩碼,如果掩碼為True,表示選擇該行;如果為False,表示忽略該行。同理,資料框中的所有列也構成一個序列,每列都對應一個掩碼,如果掩碼為True,表示選擇該列;如果為False,表示忽略該列。
使用連續的標籤,獲得資料框的一個切片:
df.loc[0:1]
使用多個離散的標籤獲得特定的行和列:
df.loc[[0,2],["A","D"]]
2,基於位置的選擇
.iloc屬性用於基於位置的選擇,位置序號從0開始,到軸長(axis length-1)截止:
- 單個位置
- 多個離散的位置
- 連續的位置
- 布林掩碼陣列
跟基於標籤的選項相比,只不過把標籤換成了位置。
三,布林掩碼索引
布林操作符是: &, | , ~,分別表示 與、或、非。通過操作符,可以把多個布林值組合成一個邏輯表示式。
當使用布林掩碼向量來作為索引時,布林向量的長度必須和索引的長度相同。這就意味著,如果一個序列有5行,那麼布林向量必須有5行;如果一個資料框有6列,那麼用於選擇列的布林向量必須有5個元素。
例如,獲得列A的資料,獲得一個序列,對序列進行邏輯運算,得到一個布林向量:
df["A"]>0
用布林向量來過濾資料行,得到基於資料掩碼的選擇:
df.loc[df["A"]>0,["A","B"]]
使用布林掩碼向量作為行索引,由於行索引有8個,即Range(8),因此,布林掩碼向量必須有8行。df["A"]>0 返回一個布林向量,是由8個布林值構成的向量。當元素值是Ture時,表示選擇該行;當元素值是False時,表示忽略該行。
也可以對布林向量進行邏輯運算,比如:
s[(s < -1) | (s > 0.5)]
四,通過可呼叫的函式來選擇資料
資料框和序列的 .loc, .iloc 和 [] 都可以接收一個可呼叫的函式( callable function)作為索引, 可呼叫的函式必須只有一個引數,並且引數是序列或資料框,返回的是布林掩碼向量。
舉個例子,使用lambda定義函式,下面兩個指令碼是等價的。
df.loc[lambda df: df['A'] > 0, ["A","B"]] df.loc[df["A"]>0,["A","B"]]
五,isin函式
判斷單個值或多個值是否存在於序列或資料框中,返回的是布林值掩碼,並可以通過掩碼來會返回值:
In [157]: s.isin([v1,v2,...])
In [158]: s[s.isin([v1,v2,...])]
六,where函式和mask函式
where()函式接收的引數是布林掩碼,返回的shape跟原始的序列和資料框相同,只不過布林值為False的元素被設定為NaN,布林值為True的元素顯示為原始值,即,把布林掩碼為False的元素掩蔽。
例如,序列s是df["A"],s>0是一個布林掩碼,下面的程式碼返回的是一個序列,只不過掩碼為False的元素全部為NaN,where()函式的作用是布林掩碼為True的返回,為False的設定為NaN。
s.where(s>0)
mask()函式接收的引數也是布林掩碼,返回的shape跟原始序列或資料框也相同,只不過布林值為False的元素顯示為原始值,而布林值為True的元素顯示為NaN,即,把不二掩碼為True的元素掩蔽。
七,query()函式
query()函式可以使用表示式來選擇資料框,以簡化資料框的查詢,比如,以下兩段程式碼返回的結果是相同的,而使用query()函式的程式碼更簡潔:
# 布林組合 df[(df['a'] < df['b']) & (df['b'] < df['c'])] df.query('(a < b) & (b < c)') # isin df[df['a'].isin(df['b'])] df.query('a in b') # not in df.query('a not in b') df[~df['a'].isin(df['b'])] #布林組合 df.query('a in b and c < d') df[df['b'].isin(df['a']) & (df['c'] < df['d'])]
在query()函式中,可以使用關鍵字 index來代替資料框的index屬性:
df.query('index < b < c')
在query()函式中,使用 == [] 等價於 in;使用 != [] 等價於 not in
# in df.query('b == ["a", "b", "c"]') df[df['b'].isin(["a", "b", "c"])] # not in df.query('c != [1, 2]') df.query('[1, 2] not in c')
參考文件: