pandas 學習 第14篇:索引和選擇數據
- 2020 年 12 月 15 日
- 筆記
- pandas, Python, Python - pandas
數據框和序列結構中都有軸標籤,軸標籤的資訊存儲在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')
參考文檔: