1. 程式人生 > 其它 >datawhale學習第二章 pandas基礎

datawhale學習第二章 pandas基礎

技術標籤:python資料分析

import numpy as np
import pandas as pd

之前的版本號是1.0.5

使用pip install --upgrade pandas更新即可

一、檔案的讀取和寫入

1. 檔案讀取

pandas可以讀取的檔案格式有很多,這裡主要介紹讀取csv, excel, txt檔案。

pd.read_csv pd.read_table pd.read_excel

1.1pd.read_csv

pandas.read_csv(filepath_or_buffer, sep=', ', delimiter=None, header='infer'
, names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=
True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compression='infer', thousands=None, decimal=b'.', lineterminator=None, quotechar='"', quoting=0, escapechar=None, comment=None, encoding=None, dialect=None
, tupleize_cols=None, error_bad_lines=True, warn_bad_lines=True, skipfooter=0, doublequote=True, delim_whitespace=False, low_memory=True, memory_map=False, float_precision=None)

具體引數詳解參考:pandas引數詳解

1.2pd.read_table

pandas.read_table(filepath_or_buffer,sep='\t',delimiter=None,header='infer',names=None,
index_col=None,usecols=None,squeeze=False,prefix=None,mangle_dupe_cols=True,dtype=None,
engine=None,converters=None,true_values=None,false_values=None,skipinitialspace=False,
skiprows=None,nrows=None,na_values=None,keep_default_na=True,na_filter=True,
verbose=False,skip_blank_lines=True,parse_dates=False,infer_datetime_format=False,
keep_date_col=False,date_parser=None,dayfirst=False,iterator=False,chunksize=None,
compression='infer',thousands=None,decimal=b'.',lineterminator=None,quotechar='"',
quoting=0,escapechar=None,comment=None,encoding=None,dialect=None,tupleize_cols=None,
error_bad_lines=True,warn_bad_lines=True,skipfooter=0,doublequote=True,
delim_whitespace=False,low_memory=True,memory_map=False,float_precision=None)

pandas.read_csv引數類似,可以看到前者sep=‘,’ 後者sep='\t'

pandas.read_table官方說明地址

1.3pd.read_excel

pd.read_excel(io, sheet_name=0, header=0, names=None, index_col=None, usecols=None, squeeze=False, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, parse_dates=False, date_parser=None, thousands=None, comment=None, skipfooter=0, convert_float=True, mangle_dupe_cols=True)

引數詳解:

1.io引數

io引數可以接受的有:str,Excel檔案,xlrd.Book,路徑物件或類似檔案的物件,其中最常用的是str,一般是檔案路徑+檔名,需要注意的是檔名字不要漏掉字尾,即副檔名,表明檔案型別的那個!有時候需要對路徑中的”\”進行轉義,io引數沒有預設值,必須傳入。

2.sheet_name引數

sheet_name引數可以接收的有:str,int,list或None,預設0

其中,字串用於工作表名稱。 整數用於零索引工作表位置。 字串/整數列表用於請求多個工作表。設定None獲取所有工作表。

有時候一個excel工作簿中包含有很多個sheet工作表,如果不指定預設為0,資料讀入的時候預設讀入的是第一個位置的sheet。0就是排在第一個位置的sheet,1是排在第二位置的sheet,依次類推。

也可以傳入列表[0,1],輸出的結果是Dict,裡面存入兩個sheet的內容。

df_excel1=pd.read_excel('../data/my_excel.xlsx', sheet_name=[0,1])
type(df_excel1)  #Dict
image-20201219113935794

3.header引數

這個引數是用來指定哪一行作為列名的,預設是第0行,接收的引數可以是整數(指定第幾行作為列名),可以是有整陣列成的列表(指定哪幾行作為列名,是的,列名可以有多行,是不是有點突破認知?),也可以是None(沒有列名)。

image-20201219114419472

4.names引數

官方文件說這個引數接收 array-like, 預設 None,表示要使用的列名列表,如果不需要列名,請設定header = None,如果header = None和names引數都設定的話,依然會顯示names指定的列名。

image-20201219114808516

5.usecols引數

該引數接收字元或者類似列表的序列,預設值是None,返回的是列的子集,直白點解釋就是在讀入表格的時候不是所有的列都會被讀入,可以通過usecols引數來設定要把哪些列讀取進來。

如果是None,表示所有的列都會被讀取。

如果是列表,表示選取指定的列讀取,比如像要只讀入第n列,這樣就可以usecols=[n],如果是多列,就把多個整數放入一個列表中傳遞給引數。需要留心的是,列表中不止可以傳入整數,也可以是欄位名組成的列表。
如果是str,則可以用A表示第一列,依次類推。例如‘A,B’或者‘A,B,E:F’

注意:如果設定了names引數,注意設定的列名個數要和讀取的列數一致

image-20201219120231001 image-20201219120249790

pandas.read_excel官方說明文件

這裡有一些常用的公共引數,header=None表示第一行不作為列名,index_col表示把某一列或幾列作為索引,索引的內容將會在第三章進行詳述,usecols表示讀取列的集合,預設讀取所有的列,parse_dates表示需要轉化為時間的列,關於時間序列的有關內容將在第十章講解,nrows表示讀取的資料行數。上面這些引數在上述的三個函式裡都可以使用。

pd.read_csv('../data/my_csv.csv', index_col=['col1', 'col2'])
pd.read_csv('../data/my_csv.csv', index_col=[0,1])
pd.read_excel('../data/my_excel.xlsx', index_col=[0,1])

區別:pd.read_excel中index_col中只能傳入元素是整數的列表

這裡用的都是相對路徑引用。

在讀取 txt 檔案時,經常遇到分隔符非空格的情況, read_table 有一個分割引數 sep ,它使得使用者可以自定義分割符號,進行 txt 資料的讀取。例如,下面的讀取的表以 |||| 為分割:

image-20201219120355376

上面的結果顯然不是理想的,這時可以使用sep,同時需要指定引擎為python

image-20201219120500014

注意:sep是正則引數

在使用read_table的時候需要注意,引數sep中使用的是正則表示式,因此需要對|進行轉義變成\|,否則無法讀取到正確的結果。

2. 資料寫入

一般在資料寫入中,最常用的操作是把index設定為False,特別當索引沒有特殊意義的時候,這樣的行為能把索引在儲存的時候去除。

df_csv.to_csv('../data/my_csv_saved.csv', index=False)
df_excel.to_excel('../data/my_excel_saved.xlsx', index=False)

pandas中沒有定義to_table函式,但是to_csv可以儲存為txt檔案,並且允許自定義分隔符,常用製表符\t分割:

df_txt.to_csv('../data/my_txt_saved.txt', sep='\t', index=False)

與上面pd.read_csv()與pd.read_table()的區別對應,sep不一樣。

如果想要把表格快速轉換為markdownlatex語言,可以使用to_markdownto_latex函式,此處需要安裝tabulate包。

image-20201219121234312

二、基本資料結構

pandas中具有兩種基本的資料儲存結構,儲存一維valuesSeries和儲存二維valuesDataFrame,在這兩種結構上定義了很多的屬性和方法。

1. Series

Series一般由四個部分組成,分別是序列的值data、索引index、儲存型別dtype、序列的名字name。其中,索引也可以指定它的名字,預設為空。

s = pd.Series(data = [100, 'a', {'dic1':5}],                         #序列的值
              index = pd.Index(['id1', 20, 'third'], name='my_idx'), #指定index的名字
              dtype = 'object',                                      #指定儲存型別
              name = 'my_name')                                      #序列的名字
s
'''my_idx
id1              100
20                 a
third    {'dic1': 5}
Name: my_name, dtype: object'''

【NOTE】object型別

object代表了一種混合型別,正如上面的例子中儲存了整數、字串以及Python的字典資料結構。此外,目前pandas把純字串序列也預設認為是一種object型別的序列,但它也可以用string型別儲存。

pd.Series()可以用字典結構為引數。

s=pd.Series({'a':1,'b':2,'c':3,'f':4,'e':5})

pd.Series官網文件

pd.Series的這些屬性可以通過.的方式來獲取:

image-20201219141730500

還有pd.Series.is_monotonic返回一個布林值(若值是單調遞增的則返回True)

pd.Series.is_monotonic_decreasing是單調遞減返回True

pd.Series.is_monotonic_increasing與第一個一樣

索引是pandas中最重要的概念之一,它將在第三章中被詳細地討論。如果想要取出單個索引對應的值,可以通過[index_item]可以取出。

2. DataFrame

DataFrameSeries的基礎上增加了列索引columns,一個數據框可以由二維的data與行列索引來構造:

image-20201219143112223

但一般而言,更多的時候會採用從列索引名到資料的對映來構造資料框,同時再加上行索引:

image-20201219143139590

這裡的data還可以傳入ndarray等

image-20201219143743267

由於這種對映關係,在DataFrame中可以用[col_name][col_list]來取出相應的列與由多個列組成的表,結果分別為SeriesDataFrame

注意:DataFrame在取相應的列時,當傳入的是[col_name_1,col_name_2](一個list)時,返回的是DataFrame,而只是傳入一個col_name,則返回的是Series

image-20201219144743223

Series類似,在資料框中同樣可以取出相應的屬性:

image-20201219144823618

通過.T可以把DataFrame進行轉置(Series也有.T屬性,返回的就是自身):

image-20201219145039973

三、常用基本函式

為了進行舉例說明,在接下來的部分和其餘章節都將會使用一份learn_pandas.csv的虛擬資料集,它記錄了四所學校學生的體測個人資訊。

image-20201219145734243

上述列名依次代表學校、年級、姓名、性別、身高、體重、是否為轉系生、體測場次、測試時間、1000米成績,本章只需使用其中的前七列,則用上面提到的方法。

image-20201219150021646

1. 彙總函式

head, tail函式分別表示返回表或者序列的前n行和後n行,其中n預設為5:

image-20201219150114102

info, describe分別返回表的資訊概況和表中數值列對應的主要統計量 :

image-20201219150415420

df.info()引數:
**verbose:**是否列印完整的摘要。 True或False會覆蓋顯示。
**buf:**可寫緩衝區,預設為sys.stdout
**max_cols:**類似控制是否列印完整的摘要,接收int
**memory_usage:**指定是否應顯示DataFrame元素(包括索引)的總記憶體使用情況。螢幕上將不顯示任何內容。True或False會覆蓋顯示。 “ deep”的值與True相同,具有自省性。記憶體使用情況以人類可讀的單位(以2為基數的表示形式)顯示。

**null_counts:**是否顯示非空計數。如果為None,則僅顯示框架是否小於max_info_rows和max_info_columns。如果為True,則始終顯示計數。如果為False,則從不顯示計數。

image-20201219152446469

max_cols小於DataFrame的列時,類似於verbose=False。反之,類似於verbose=True

image-20201219153722654

.describe()官方文件

DataFrame.describe(percentiles=None, include=None,exclude=None,datetime_is_numeric=False)

其物理意義在於觀察這一系列資料的範圍。大小、波動趨勢等等,便於判斷後續對資料採取哪類模型更合適。

image-20201219154610000

1.第一個percentiles,這個引數可以設定數值型特徵的統計量,預設是[.25, .5, .75],也就是返回25%,50%,75%資料量時的數字,但是這個可以修改的.預設是有50%的

image-20201219154740778

2.第二個引數:include,這個引數預設是隻計算數值型特徵的統計量(這就是為什麼只有兩列的統計量),當輸入include=[‘O’],會計算離散型變數的統計特徵。此外傳引數是‘all’的時候會把數值型和離散型特徵的統計都進行顯示。

image-20201219155732754

3.第三個引數的設計就更貼心了,第二個引數是你可以指定選那些,第三個引數就是你可以指定不選哪些,人性化設計。這個引數預設不丟棄任何列,相當於無影響。

【NOTE】更全面的資料彙總

info, describe只能實現較少資訊的展示,如果想要對一份資料集進行全面且有效的觀察,特別是在列較多的情況下,推薦使用pandas-profiling包,它將在第十一章被再次提到。

2. 特徵統計函式

SeriesDataFrame上定義了許多統計函式,最常見的是sum, mean, median, var, std, max, min。例如,選出身高和體重列進行演示:

image-20201219160647682

此外,需要介紹的是quantile, count, idxmax這三個函式,它們分別返回的是分位數、非缺失值個數、最大值對應的索引:

image-20201219160816998

上面這些所有的函式,由於操作後返回的是標量,所以又稱為聚合函式,它們有一個公共引數axis,預設為0代表逐列聚合,如果設定為1則表示逐行聚合:

image-20201219161230406

3. 唯一值函式

對序列使用uniquenunique可以分別得到其唯一值組成的列表和唯一值的個數:

image-20201219162305307

value_counts可以得到唯一值和其對應出現的頻數:

image-20201219162448961

如果想要觀察多個列組合的唯一值,可以使用drop_duplicates。其中的關鍵引數是keep,預設值first表示每個組合保留第一次出現的所在行,last表示保留最後一次出現的所在行,False表示把所有重複組合所在的行剔除。

DataFrame.drop_duplicates(subset=None, keep='first', inplace=False, ignore_index=False)

官方文件說明

image-20201219164812594
df_demo.drop_duplicates(['Name', 'Gender'], keep=False) #結果是164X3
df_demo.drop_duplicates(['Name', 'Gender'], keep='last')#結果是181X3

從這裡可以看出keep=False,把所有重複的都刪掉了。

此外,inplace=Ture則在df上原地修改,不會返回一個df

image-20201219202409873

此外,duplicateddrop_duplicates的功能類似,但前者返回了是否為唯一值的布林列表,其keep引數與後者一致。其返回的序列,把重複元素設為True,否則為False

image-20201219202906872

就是和drop_duplicated一樣,只是duplicated返回的是布林值。 drop_duplicates等價於把duplicatedTrue的對應行剔除。

4. 替換函式

一般而言,替換操作是針對某一個列進行的,因此下面的例子都以Series舉例。pandas中的替換函式可以歸納為三類:對映替換、邏輯替換、數值替換。其中對映替換包含replace方法、第八章中的str.replace方法以及第九章中的cat.codes方法,此處介紹replace的用法。

DataFrame.replace(to_replace=None,value=None,inplace=False,limit=None,regex=False,method='pad')

官方文件

replace中,可以通過字典構造,或者傳入兩個列表來進行替換:

image-20201219203327802

另外,replace還有一種特殊的方向替換,指定method引數為ffill則為用前面一個最近的未被替換的值進行替換,bfill則使用後面最近的未被替換的值進行替換。從下面的例子可以看到,它們的結果是不同的:

image-20201219203431987

記憶:ffill->forward往前,bfill->back往後

最後,limit引數是規定ffill與bfill來往前或往後尋找值填充的最大gap,下面就是隻在後面一位填充

image-20201219204540709

【WARNING】正則替換請使用str.replace[¶](http://localhost:8888/notebooks/Documents/機器學習/datawhale/joyful-pandas-master/notebook/第二章 pandas基礎.ipynb#[WARNING]正則替換請使用str.replace)

雖然對於replace而言可以使用正則替換,但是當前版本下對於string型別的正則替換還存在bug,因此如有此需求,請選擇str.replace進行替換操作,具體的方式將在第八章中講解。

邏輯替換包括了wheremask,這兩個函式是完全對稱的:where函式在傳入條件為False的對應行進行替換,而mask在傳入條件為True的對應行進行替換,當不指定替換值時,替換為缺失值。

image-20201219205657865 image-20201219205720472

需要注意的是,傳入的條件只需是與被呼叫的Series索引一致的布林序列即可:

image-20201219205936889

數值替換包含了round, abs, clip方法,它們分別表示按照給定精度四捨五入、取絕對值和截斷:

image-20201219210111295 image-20201219210357183

【練一練】

在 clip 中,超過邊界的只能截斷為邊界值,如果要把超出邊界的替換為自定義的值,應當如何做?

image-20201219210853824

5. 排序函式

排序共有兩種方式,其一為值排序,其二為索引排序,對應的函式是sort_valuessort_index

為了演示排序函式,下面先利用set_index方法把年級和姓名兩列作為索引,多級索引的內容和索引設定的方法將在第三章進行詳細講解。

image-20201219211120269

對身高進行排序,預設引數ascending=True為升序:

image-20201219211246352

在排序中,經常遇到多列排序的問題,比如在體重相同的情況下,對身高進行排序,並且保持身高降序排列,體重升序排列:

image-20201219211338138

這裡就是先對Weight排序,在對Height排序,其中前者是升序後者是降序。注意這裡引數傳入的是列表。

索引排序的用法和值排序完全一致,只不過元素的值在索引中,此時需要指定索引層的名字或者層號,用引數level表示。另外,需要注意的是字串的排列順序由字母順序決定。

image-20201219211552720

6. apply方法

apply方法常用於DataFrame的行迭代或者列迭代,它的axis含義與第2小節中的統計聚合函式一致,apply的引數往往是一個以序列為輸入的函式。例如對於.mean(),使用apply可以如下地寫出:

image-20201219211723711

同樣的,可以利用lambda表示式使得書寫簡潔,這裡的x就指代被呼叫的df_demo表中逐個輸入的序列。

image-20201219211932248

若指定axis=1,那麼每次傳入函式的就是行元素組成的Series,其結果與之前的逐行均值結果一致。

image-20201219211951025

這裡再舉一個例子:mad函式返回的是一個序列中偏離該序列均值的絕對值大小的均值,例如序列1,3,7,10中,均值為5.25,每一個元素偏離的絕對值為4.25,2.25,1.75,4.75,這個偏離序列的均值為3.25。現在利用apply計算升高和體重的mad指標:

image-20201219212029394

【WARNING】謹慎使用apply

得益於傳入自定義函式的處理,apply的自由度很高,但這是以效能為代價的。一般而言,使用pandas的內建函式處理和apply來處理同一個任務,其速度會相差較多,因此只有在確實存在自定義需求的情境下才考慮使用apply

四、視窗物件

pandas中有3類視窗,分別是滑動視窗rolling、擴張視窗expanding以及指數加權視窗ewm。需要說明的是,以日期偏置為視窗大小的滑動視窗將在第十章討論,指數加權視窗見本章練習。

1. 滑窗物件

要使用滑窗函式,就必須先要對一個序列使用.rolling得到滑窗物件,其最重要的引數為視窗大小window

image-20201219212255940

得到了一個Rolling物件。

在得到了滑窗物件後,能夠使用相應的聚合函式進行計算,需要注意的是視窗包含當前行所在的元素,例如在第四個位置進行均值運算時,應當計算(2+3+4)/3,而不是(1+2+3)/3:

image-20201219212349094

對於滑動相關係數或滑動協方差的計算,可以如下寫出:

image-20201219212520951

roller.cov(s2)第三個值2.5 就是(1,2,3)與(1,2,6)的cov,往後依次滑動。

此外,還支援使用apply傳入自定義函式,其傳入值是對應視窗的Series,例如上述的均值函式可以等效表示:

image-20201219212814542

shift, diff, pct_change是一組類滑窗函式,它們的公共引數為periods=n,預設為1,分別表示取向前第n個元素的值、與向前第n個元素做差(與Numpy中不同,後者表示n階差分)、與向前第n個元素相比計算增長率。這裡的n可以為負,表示反方向的類似操作。

image-20201219213248469

這裡的增加率計算:設當前索引為k, p c t = s [ k ] − s [ k − n ] s [ k − n ] pct=\frac{s[k]-s[k-n]}{s[k-n]} pct=s[kn]s[k]s[kn]

image-20201219213552896

將其視作類滑窗函式的原因是,它們的功能可以用視窗大小為n+1rolling方法等價代替:

image-20201219213939390 image-20201219214034236

【練一練】

rolling物件的預設視窗方向都是向前的,某些情況下使用者需要向後的視窗,例如對1,2,3設定向後窗口為2的sum操作,結果為3,5,NaN,此時應該如何實現向後的滑窗操作?

image-20201219215236210

2. 擴張視窗

擴張視窗又稱累計視窗,可以理解為一個動態長度的視窗,其視窗的大小就是從序列開始處到具體操作的對應位置,其使用的聚合函式會作用於這些逐步擴張的視窗上。具體地說,設序列為a1, a2, a3, a4,則其每個位置對應的視窗即[a1]、[a1, a2]、[a1, a2, a3]、[a1, a2, a3, a4]。

image-20201219214939442

【練一練】

cummax, cumsum, cumprod函式是典型的類擴張視窗函式,請使用expanding物件依次實現它們。

image-20201219225511536 image-20201219225530803