首先我們要明確索引的作用汁展。在SQL中我們通過索引能夠快速的定位數(shù)據(jù)貌夕,就像一本書的目錄一樣,通過目錄我們可以快速的定位到書中的某個章節(jié)踊挠。在pandas里面,我們通過索引進行數(shù)據(jù)的選取和篩選冲杀。就像在一張大表里面選取我們需要分析或者感興趣的內(nèi)容效床,此時就需要用到索引的相關(guān)操作。這個是pandas中基本操作权谁,需要熟練掌握剩檀。因為一維的Series比較簡單,我們以二維的數(shù)據(jù)結(jié)構(gòu)DataFrame為例進行總結(jié)旺芽。主要包括以下內(nèi)容:
- 列選取沪猴,選取一列或者多列
- 行選取
- loc和iloc選取(主要內(nèi)容采章,經(jīng)常用)
- Query方法選取
下面通過代碼實戰(zhàn)進行演練运嗜。下面代碼中涉及的數(shù)據(jù)集和代碼可以在后臺回復(fù)“pandas”獲取
import numpy as np
import pandas as pd
df = pd.read_csv('learn_pandas.csv')
df.head()
這是一個包含學(xué)生姓名/性別和學(xué)校以及身高體重等信息的表格
1.列選饶稹:根據(jù)要求選擇一列或者多列
對于DataFrame的列叠纷,可以使用“[]”操作符或者"."進行選擇,使用“.”時要注意鲫构,列明不能有空格如下:
# 通過列標(biāo)簽選擇數(shù)據(jù)
df['School'].head()
>>>
0 Shanghai Jiao Tong University
1 Peking University
2 Shanghai Jiao Tong University
3 Fudan University
4 Fudan University
Name: School, dtype: object
要同時選取多列時抵怎,一般是先創(chuàng)建一個列表奋救,將所需要的內(nèi)容放入列表中,再將該列表整體傳入df中:
use_col = ['Name', 'Gender', 'Height', 'Test_Date']
df[use_col].head(5)
結(jié)果如下:
2. 行選取
當(dāng)要求按照某個字段的條件篩選某些行時反惕,可以直接將該條件作為一個condition傳入df中尝艘,舉例:
- 篩選 Peking University的學(xué)生:
# 直接按照條件帶入帶入:
df[df['School'] == 'Peking University'].head()
# 上面的寫法等價于:
condition = (df['School'] == 'Peking University')
df[condition].head
>>>
結(jié)果如下:
- 篩選身高大于165的同學(xué):
df[df['Height'] > 165].head()
3. loc和iloc
在實際實戰(zhàn)中,按照一定條件選擇數(shù)據(jù)更常用的方法是loc和iloc, 兩者的語法結(jié)構(gòu)類似姿染,不同之處在于:
- loc : 基于label索引器背亥,列名和行號都可以作為label
- iloc: 基于index索引的索引器
這兩個容易混淆,實際中可以按照首字母記憶盔粹,即loc和label都是“l(fā)”開頭隘梨,iloc和index都是“i”開頭。
語法結(jié)構(gòu)以loc為例舷嗡,iloc一樣:
df. loc[*, *] 轴猎,其中第一個 * 代表行的選擇,第二個 * 代表列的選擇进萄,如果省略第二個位置寫作 loc[] 捻脖,這個 * 是指行的篩選锐峭。
其中, * 的位置一共有五類合法對象可婶,分別是:單個元素沿癞、元素列表、元素切片矛渴、布爾列表以及函數(shù)椎扬,常用的為前面4個,下面將依次說明具温。
我們以loc為例蚕涤,前面說了,loc是基于label選取的铣猩,我們把行索引index設(shè)置為Name,這樣更容易說明揖铜。
df_new = df.set_index('Name')
df_new.head()
【a】 * 為單個元素
此時,直接取出相應(yīng)的行或列达皿,如果該元素在索引中重復(fù)則結(jié)果為 DataFrame天吓,否則為 Series
df_new.loc['Gaojuan You'] # 原表格中只有一行滿足條件,返回一個Series
>>>
School Fudan University
Grade Sophomore
Gender Male
Height 174.0
Weight 74.0
Transfer N
Test_Number 2
Test_Date 2019/11/6
Time_Record 0:05:22
Name: Gaojuan You, dtype: object
df_new.loc['Qiang Sun'] # 原表格中有多行滿足條件,返回一個DataFrame
【b】 * 為元素列表
此時,取出列表中所有元素值對應(yīng)的行或列:
df_new.loc[['Qiang Sun', 'Xiaojuan Sun'],['School', 'Gender', 'Weight']]
【c】 * 為切片
之前的 Series 使用字符串索引時提到峦椰,如果是唯一值的起點和終點字符龄寞,那么就可以使用切片,并且包含兩個端點们何,如果不唯一則報錯:
df_new.loc['Changqiang You':'Gaoqiang Qian', 'School':'Test_Number']
【d】 * 為布爾列表
在前面的行選取中萄焦,其實我們已經(jīng)使用了和loc布爾列表類似的操作了。我們在來看一下上面例子中的表達式: df[df['Height'] > 165]冤竹,在該表達式中:
- 第一步:內(nèi)部的“df['Height'] > 165” 返回一個與 DataFrame 長度相同的布爾列表
- 第二步:外面在套上df后,實際上執(zhí)行了一個篩選操作茬射,即且列表為 True 的位置所對應(yīng)的行會被選中鹦蠕, False 則會被剔除。
df.loc也可以完成相同的功能:
(df.loc[df['School'] == 'Tsinghua University' ]) == (df[df['School'] == 'Tsinghua University'])
在實際操作中在抛,往往需要根據(jù)多個條件來選取數(shù)據(jù)钟病,對于這種復(fù)合條件而言,可以用 |(或), &(且), ~(取反) 的組合來實現(xiàn)刚梭。
實戰(zhàn)操作: 選取復(fù)旦大學(xué)中體重超過70kg的大四學(xué)生肠阱,或者北大男生中體重超過80kg的非大四的學(xué)生:
condition_1_a = df_new['School'] == 'Fudan University'
condition_1_b = df_new['Grade'] == 'Senior'
condition_1_c = df_new['Weight'] > 70
condition_1 = condition_1_a & condition_1_b & condition_1_c
condition_2_a = df_new.School == 'Peking University'
condition_2_b = df_new.Grade == 'Senior'
condition_2_c = df_new.Weight > 80
condition_2 = condition_2_a & (~condition_2_b) & condition_2_c
res = df_new.loc[condition_1 | condition_2]
res
結(jié)果如下:
iloc 的使用與 loc 完全類似,只不過是針對index索引進行篩選朴读,因為行/列的索引index均是從0開始的整數(shù)屹徘,因而在相應(yīng)的 * 位置處一共也有五類合法對象,分別是:整數(shù)衅金、整數(shù)列表噪伊、整數(shù)切片簿煌、布爾列表以及函數(shù),函數(shù)的返回值必須是前面的四類合法對象中的一個鉴吹,其輸入同樣也為 DataFrame 本身姨伟。
這個方法有一個常用的場景,就是在機器學(xué)習(xí)的數(shù)據(jù)集劃分中豆励。例如在一個大表中夺荒,前面的列為特征,最后一列為對應(yīng)的標(biāo)簽良蒸,這時需要將除去最后一列的數(shù)據(jù)作為X,最后一列的值作為標(biāo)簽Y般堆,例如在上面的表格中,我們可以:
X = df.iloc[:, :-1] # : 前面為行诚啃,不寫表示選取所有行淮摔,后面為列,-1為最后一列始赎,不包括
Y = df['Time_Record']
4. Query方法
在 pandas 中和橙,支持把字符串形式的查詢表達式傳入 query 方法來查詢數(shù)據(jù),其表達式的執(zhí)行結(jié)果必須返回布爾列表造垛。在進行復(fù)雜索引時魔招,由于這種檢索方式無需像普通方法一樣重復(fù)使用 DataFrame 的名字來引用列名,一般而言會使代碼長度在不降低可讀性的前提下有所減少五辽。
例如办斑,可以將上面loc方法的復(fù)合選取改用query方法來做:
# 將 loc 一節(jié)中的復(fù)合條件查詢例子可以如下改寫:
df.query('((School == "Fudan University")&'
' (Grade == "Senior")&'
' (Weight > 70))|'
'((School == "Peking University")&'
' (Grade != "Senior")&'
' (Weight > 80))')
在 query 表達式中,系統(tǒng)自動幫用戶注冊了所有來自 DataFrame 的列名杆逗,所有屬于該 Series 的方法都可以被調(diào)用乡翅,和正常的函數(shù)調(diào)用并沒有區(qū)別,即在調(diào)用是無需在聲明df['列名‘]的形式罪郊,直接使用列名蠕蚜。例如查詢體重超過均值且性別為女的學(xué)生:
df.query('(Weight > Weight.mean())' and '(Gender == "Female")').head(6)
部分結(jié)果如下:
參考:開源內(nèi)容Joyful Pandas, 作者 DataWhale耿遠昊
另外,更多精彩內(nèi)容也可以微信搜索悔橄,并關(guān)注公眾號:‘Python數(shù)據(jù)科學(xué)家之路“ 靶累,期待您的到來和我交流