pandas 學習 第14篇:索引和選擇數據

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