pandas 學習 第14篇:索引和選擇資料

悅光陰發表於2020-12-15

資料框和序列結構中都有軸標籤,軸標籤的資訊儲存在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')

 

 

 

 

參考文件:

Indexing and selecting data

Intro Pandas

相關文章