使用Pandas&NumPy進行數據清洗的6大常用方法

數據科學家花了大量的時間清洗數據集,並將這些數據轉換為他們可以處理的格式。事實上,很多數據科學家聲稱開始獲取和清洗數據的工作量要佔整個工作的80%。

因此,如果你正巧也在這個領域中,或者計划進入這個領域,那麼處理這些雜亂不規則數據是非常重要的,這些雜亂數據包括一些缺失值,不連續格式,錯誤記錄,或者是沒有意義的異常值。

在這個教程中,我們將利用Python的PandasNumpy包來進行數據清洗。

主要內容如下:

  • 刪除 DataFrame 中的不必要 columns
  • 改變 DataFrame 的 index
  • 使用 .str() 方法來清洗 columns
  • 使用 DataFrame.applymap() 函數按元素清洗整個數據集
  • 重命名 columns 為一組更易識別的標籤
  • 濾除 CSV文件中不必要的 rows

下面是要用到的數據集:

  • BL-Flickr-Images-Book.csv : 一份來自英國圖書館包含關於書籍信息的CSV文檔
  • university_towns.txt : 一份包含美國各大洲大學城名稱的text文檔
  • olympics.csv : 一份總結了各國家參加夏季與冬季奧林匹克運動會情況的CSV文檔

你可以從Real Python 的 GitHub repository 下載數據集來進行下面的例子。

注意:建議使用Jupter Notebooks來學習下面的知識。

學習之前假設你已經有了對Pandas和Numpy庫的基本認識,包括Pandas的工作基礎SeriesDataFrame對象,應用到這些對象上的常用方法,以及熟悉了NumPy的NaN值。

讓我們導入這些模塊開始我們的學習。

1>>> import pandas as pd2>>> import numpy as np

刪除DataFrame的列

經常的,你會發現數據集中不是所有的欄位類型都是有用的。例如,你可能有一個關於學生信息的數據集,包含姓名,分數,標準,父母姓名,住址等具體信息,但是你只想分析學生的分數。

這個情況下,住址或者父母姓名信息對你來說就不是很重要。這些沒有用的信息會佔用不必要的空間,並會使運行時間減慢。

Pandas提供了一個非常便捷的方法drop()函數來移除一個DataFrame中不想要的行或列。讓我們看一個簡單的例子如何從DataFrame中移除列。

首先,我們引入BL-Flickr-Images-Book.csv文件,並創建一個此文件的DataFrame。在下面這個例子中,我們設置了一個pd.read_csv的相對路徑,意味著所有的數據集都在Datasets文件夾下的當前工作目錄中:

1>>> df = pd.read_csv(Datasets/BL-Flickr-Images-Book.csv) 2>>> df.head() 3 Identifier Edition Statement Place of Publication 40 206 NaN London 51 216 NaN London; Virtue & Yorston 62 218 NaN London 73 472 NaN London 84 480 A new edition, revised, etc. London 9 Date of Publication Publisher 100 1879 [1878] S. Tinsley & Co.111 1868 Virtue & Co.122 1869 Bradbury, Evans & Co.133 1851 James Darling144 1857 Wertheim & Macintosh15 Title Author 160 Walter Forbes. [A novel.] By A. A A. A.171 All for Greed. [A novel. The dedication signed... A., A. A.182 Love the Avenger. By the author of 「All for Gr... A., A. A.193 Welsh Sketches, chiefly ecclesiastical, to the... A., E. S.204 [The World in which I live, and my place in it... A., E. S.21 Contributors Corporate Author 220 FORBES, Walter. NaN231 BLAZE DE BURY, Marie Pauline Rose - Baroness NaN242 BLAZE DE BURY, Marie Pauline Rose - Baroness NaN253 Appleyard, Ernest Silvanus. NaN264 BROOME, John Henry. NaN27 Corporate Contributors Former owner Engraver Issuance type 280 NaN NaN NaN monographic291 NaN NaN NaN monographic302 NaN NaN NaN monographic313 NaN NaN NaN monographic324 NaN NaN NaN monographic33 Flickr URL 340 http://www.flickr.com/photos/britishlibrary/ta...351 http://www.flickr.com/photos/britishlibrary/ta...362 http://www.flickr.com/photos/britishlibrary/ta...373 http://www.flickr.com/photos/britishlibrary/ta...384 http://www.flickr.com/photos/britishlibrary/ta...39 Shelfmarks400 British Library HMNTS 12641.b.30.411 British Library HMNTS 12626.cc.2.422 British Library HMNTS 12625.dd.1.433 British Library HMNTS 10369.bbb.15.444 British Library HMNTS 9007.d.28.

我們使用了head()方法得到了前五個行信息,這些列提供了對圖書館有幫助的輔助信息,但是並不能很好的描述這些書籍:Edition Statement, Corporate Author, Corporate Contributors, Former owner, Engraver, Issuance type and Shelfmarks

因此,我們可以用下面的方法移除這些列:

1>>> to_drop = [Edition Statement,2... Corporate Author,3... Corporate Contributors,4... Former owner,5... Engraver,6... Contributors,7... Issuance type,8... Shelfmarks]9>>> df.drop(to_drop, inplace=True, axis=1)

在上面,我們定義了一個包含我們不要的列的名稱列表。接著,我們在對象上調用drop()函數,其中inplace參數是Trueaxis參數是1。這告訴了Pandas,我們想要直接在我們的對象上發生改變,並且它應該可以尋找對象中被移除列的信息。

我們再次看一下DataFrame,我們會看到不想要的信息已經被移除了。

1>>> df.head() 2 Identifier Place of Publication Date of Publication 30 206 London 1879 [1878] 41 216 London; Virtue & Yorston 1868 52 218 London 1869 63 472 London 1851 74 480 London 1857 8 Publisher Title 90 S. Tinsley & Co. Walter Forbes. [A novel.] By A. A101 Virtue & Co. All for Greed. [A novel. The dedication signed...112 Bradbury, Evans & Co. Love the Avenger. By the author of 「All for Gr...123 James Darling Welsh Sketches, chiefly ecclesiastical, to the...134 Wertheim & Macintosh [The World in which I live, and my place in it...14 Author Flickr URL150 A. A. http://www.flickr.com/photos/britishlibrary/ta...161 A., A. A. http://www.flickr.com/photos/britishlibrary/ta...172 A., A. A. http://www.flickr.com/photos/britishlibrary/ta...183 A., E. S. http://www.flickr.com/photos/britishlibrary/ta...194 A., E. S. http://www.flickr.com/photos/britishlibrary/ta...

同樣的,我們也可以通過給columns參數賦值直接移除列,而就不用分別定義to_drop列表和axis了。

1>>> df.drop(columns=to_drop, inplace=True)

這種語法更直觀更可讀。我們這裡將要做什麼就很明顯了。

改變DataFrame的索引

Pandas索引index擴展了Numpy數組的功能,以允許更多多樣化的切分和標記。在很多情況下,使用唯一的值作為索引值識別數據欄位是非常有幫助的。

例如,仍然使用上一節的數據集,可以想像當一個圖書管理員尋找一個記錄,他們也許會輸入一個唯一標識來定位一本書。

1>>> df[Identifier].is_unique2True

讓我們用set_index把已經存在的索引改為這個列。

1>>> df = df.set_index(Identifier) 2>>> df.head() 3 Place of Publication Date of Publication 4206 London 1879 [1878] 5216 London; Virtue & Yorston 1868 6218 London 1869 7472 London 1851 8480 London 1857 9 Publisher 10206 S. Tinsley & Co.11216 Virtue & Co.12218 Bradbury, Evans & Co.13472 James Darling14480 Wertheim & Macintosh15 Title Author 16206 Walter Forbes. [A novel.] By A. A A. A.17216 All for Greed. [A novel. The dedication signed... A., A. A.18218 Love the Avenger. By the author of 「All for Gr... A., A. A.19472 Welsh Sketches, chiefly ecclesiastical, to the... A., E. S.20480 [The World in which I live, and my place in it... A., E. S.21 Flickr URL22206 http://www.flickr.com/photos/britishlibrary/ta...23216 http://www.flickr.com/photos/britishlibrary/ta...24218 http://www.flickr.com/photos/britishlibrary/ta...25472 http://www.flickr.com/photos/britishlibrary/ta...26480 http://www.flickr.com/photos/britishlibrary/ta...

技術細節:不像在SQL中的主鍵一樣,pandas的索引不保證唯一性,儘管許多索引和合併操作將會使運行時間變長如果是這樣。

我們可以用一個直接的方法loc[]來獲取每一條記錄。儘管loc[]這個詞可能看上去沒有那麼直觀,但它允許我們使用基於標籤的索引,這個索引是行的標籤或者不考慮位置的記錄。

1>>> df.loc[206]2Place of Publication London3Date of Publication 1879 [1878]4Publisher S. Tinsley & Co.5Title Walter Forbes. [A novel.] By A. A6Author A. A.7Flickr URL http://www.flickr.com/photos/britishlibrary/ta...8Name: 206, dtype: object

換句話說,206是索引的第一個標籤。如果想通過位置獲取它,我們可以使用df.iloc[0],是一個基於位置的索引。

之前,我們的索引是一個範圍索引:從0開始的整數,類似Python的內建range。通過給set_index一個列名,我們就把索引變成了Identifier中的值。

你也許注意到了我們通過df = df.set_index(...)的返回變數重新給對象賦了值。這是因為,默認的情況下,這個方法返回一個被改變對象的拷貝,並且它不會直接對原對象做任何改變。我們可以通過設置參數inplace來避免這個問題。

1df.set_index(Identifier, inplace=True)

清洗數據欄位

到現在為止,我們移除了不必要的列並改變了我們的索引,讓它們變得更有意義。這個部分,我們將清洗特殊的列,並使它們變成統一的格式,這樣可以更好的理解數據集和加強連續性。特別的,我們將清洗Date of PublicationPlace of Publication

根據上面觀察,所有的數據類型都是objectdtype類型,差不多類似於Python中的str。

它包含了一些不能被適用於數值或是分類的數據。這也正常,因為我們正在處理這些初始值就是雜亂無章字元串的數據。

1>>> df.get_dtype_counts()2object 6

一個需要被改變為數值的的欄位是date of publication所以我們做如下操作:

1>>> df.loc[1905:, Date of Publication].head(10) 2Identifier 31905 1888 41929 1839, 38-54 52836 [1897?] 62854 1865 72956 1860-63 82957 1873 93017 1866103131 1899114598 1814124884 182013Name: Date of Publication, dtype: object

一本書只能有一個出版日期data of publication。因此,我們需要做以下的一些事情:

  • 移除在方括弧內的額外日期,任何存在的:1879[1878]。
  • 將日期範圍轉化為它們的起始日期,任何存在的:1860-63;1839,38-54。
  • 完全移除我們不關心的日期,並用Numpy的NaN替換:[1879?]。
  • 將字元串nan轉化為Numpy的NaN值。

考慮這些模式,我們可以用一個簡單的正則表達式來提取出版日期:

1regex = r^(d{4})

上面正則表達式的意思在字元串開頭尋找任何四位數字,符合我們的情況。

d代表任何數字,{4}重複這個規則四次。^符號匹配一個字元串最開始的部分,圓括弧表示一個分組,提示pandas我們想要提取正則表達式的部分。

讓我們看看運行這個正則在數據集上之後會發生什麼。

1>>> extr = df[Date of Publication].str.extract(r^(d{4}), expand=False)2>>> extr.head()3Identifier4206 18795216 18686218 18697472 18518480 18579Name: Date of Publication, dtype: object

其實這個列仍然是一個object類型,但是我們可以使用pd.to_numeric輕鬆的得到數字的版本:

1>>> df[Date of Publication] = pd.to_numeric(extr)2>>> df[Date of Publication].dtype3dtype(float64)

這個結果中,10個值里大約有1個值缺失,這讓我們付出了很小的代價來對剩餘有效的值做計算。

1>>> df[Date of Publication].isnull().sum() / len(df)20.11717147339205986

結合str方法與Numpy清洗列

上面,你可以觀察到df[Date of Publication].str.的使用。這個屬性是pandas里的一種提升字元串操作速度的方法,並有大量的Python字元串或編譯的正則表達式上的小操作,例如.split(),.replace(),和.capitalize()

為了清洗Place of Publication欄位,我們可以結合pandas的str方法和numpy的np.where函數配合完成。

它的語法如下:

1>>> np.where(condition, then, else)

這裡,condition可以使一個類數組的對象,也可以是一個布爾表達。如果condition值為真,那麼then將被使用,否則使用else

它也可以嵌套使用,允許我們基於多個條件進行計算。

1>>> np.where(condition1, x1, 2 np.where(condition2, x2, 3 np.where(condition3, x3, ...)))

我們將使用這兩個函數來清洗Place of Publication由於這列有字元串對象。以下是這個列的內容:

1>>> df[Place of Publication].head(10) 2Identifier 3206 London 4216 London; Virtue & Yorston 5218 London 6472 London 7480 London 8481 London 9519 London10667 pp. 40. G. Bryan & Co: Oxford, 189811874 London]121143 London13Name: Place of Publication, dtype: object

我們看到,對於一些行,place of publication還被一些其它沒有用的信息圍繞著。如果我們看更多的值,我們發現這種情況只適用於place of publication是"London"或者"Oxford"的行。

讓我們看看兩個特殊的:

1>>> df.loc[4157862] 2Place of Publication Newcastle-upon-Tyne 3Date of Publication 1867 4Publisher T. Fordyce 5Title Local Records; or, Historical Register of rema... 6Author T. Fordyce 7Flickr URL http://www.flickr.com/photos/britishlibrary/ta... 8Name: 4157862, dtype: object 9>>> df.loc[4159587]10Place of Publication Newcastle upon Tyne11Date of Publication 183412Publisher Mackenzie & Dent13Title An historical, topographical and descriptive v...14Author E. (Eneas) Mackenzie15Flickr URL http://www.flickr.com/photos/britishlibrary/ta...16Name: 4159587, dtype: object

這兩本書在同一個地方出版,但是一個有連字元,另一個沒有。

為了一次性清洗這個列,我們使用str.contains()來獲取一個布爾值。

我們清洗的列如下:

1>>> pub = df[Place of Publication] 2>>> london = pub.str.contains(London) 3>>> london[:5] 4Identifier 5206 True 6216 True 7218 True 8472 True 9480 True10Name: Place of Publication, dtype: bool11>>> oxford = pub.str.contains(Oxford)

我們將它與np.where結合。

1df[Place of Publication] = np.where(london, London, 2 np.where(oxford, Oxford, 3 pub.str.replace(-, ))) 4>>> df[Place of Publication].head() 5Identifier 6206 London 7216 London 8218 London 9472 London10480 London11Name: Place of Publication, dtype: object

這裡,np.where函數在一個嵌套的結構中被調用,condition是一個通過st.contains()得到的布爾的Seriescontains()方法與Python內建的in關鍵字一樣,用於發現一個個體是否發生在一個迭代器中。

使用的替代物是一個代表我們期望的出版社地址字元串。我們也使用str.replace()將連字元替換為空格,然後給DataFrame中的列重新賦值。

儘管數據集中還有更多的不幹凈數據,但是我們現在僅討論這兩列。

讓我們看看前五行,現在看起來比我們剛開始的時候好點了。

1>>> df.head() 2 Place of Publication Date of Publication Publisher 3206 London 1879 S. Tinsley & Co. 4216 London 1868 Virtue & Co. 5218 London 1869 Bradbury, Evans & Co. 6472 London 1851 James Darling 7480 London 1857 Wertheim & Macintosh 8 Title Author 9206 Walter Forbes. [A novel.] By A. A AA10216 All for Greed. [A novel. The dedication signed... A. A A.11218 Love the Avenger. By the author of 「All for Gr... A. A A.12472 Welsh Sketches, chiefly ecclesiastical, to the... E. S A.13480 [The World in which I live, and my place in it... E. S A.14 Flickr URL15206 http://www.flickr.com/photos/britishlibrary/ta...16216 http://www.flickr.com/photos/britishlibrary/ta...17218 http://www.flickr.com/photos/britishlibrary/ta...18472 http://www.flickr.com/photos/britishlibrary/ta...19480 http://www.flickr.com/photos/britishlibrary/ta...

在這一點上,Place of Publication就是一個很好的需要被轉換成分類數據的類型,因為我們可以用整數將這相當小的唯一城市集編碼。(分類數據的使用內存與分類的數量以及數據的長度成正比)

使用applymap方法清洗整個數據集

在一定的情況下,你將看到並不是僅僅有一條列不幹凈,而是更多的。

在一些實例中,使用一個定製的函數到DataFrame的每一個元素將會是很有幫助的。pandasapplymap()方法與內建的map()函數相似,並且簡單的應用到一個DataFrame中的所有元素上。

讓我們看一個例子。我們將基於"university_towns.txt"文件創建一個DataFrame

1$ head Datasets/univerisity_towns.txt 2Alabama[edit] 3Auburn (Auburn University)[1] 4Florence (University of North Alabama) 5Jacksonville (Jacksonville State University)[2] 6Livingston (University of West Alabama)[2] 7Montevallo (University of Montevallo)[2] 8Troy (Troy University)[2] 9Tuscaloosa (University of Alabama, Stillman College, Shelton State)[3][4]10Tuskegee (Tuskegee University)[5]11Alaska[edit]

我們可以看到每個state後邊都有一些在那個state的大學城:StateA TownA1 TownA2 StateB TownB1 TownB2...。如果我們仔細觀察state名字的寫法,我們會發現它們都有"[edit]"的自字元串。

我們可以利用這個特徵創建一個含有(state,city)元組的列表,並將這個列表嵌入到DdataFrame中,

1>>> university_towns = [] 2>>> with open(Datasets/university_towns.txt) as file: 3... for line in file: 4... if [edit] in line: 5... # Remember this `state` until the next is found 6... state = line 7... else: 8... # Otherwise, we have a city; keep `state` as last-seen 9... university_towns.append((state, line))10>>> university_towns[:5]11[(Alabama[edit]
, Auburn (Auburn University)[1]
),12 (Alabama[edit]
, Florence (University of North Alabama)
),13 (Alabama[edit]
, Jacksonville (Jacksonville State University)[2]
),14 (Alabama[edit]
, Livingston (University of West Alabama)[2]
),15 (Alabama[edit]
, Montevallo (University of Montevallo)[2]
)]

我們可以在DataFrame中包裝這個列表,並設列名為"State"和"RegionName"。pandas將會使用列表中的每個元素,然後設置State到左邊的列,RegionName到右邊的列。

最終的DataFrame是這樣的:

1>>> towns_df = pd.DataFrame(university_towns,2... columns=[State, RegionName])3>>> towns_df.head()4 State RegionName50 Alabama[edit]
Auburn (Auburn University)[1]
61 Alabama[edit]
Florence (University of North Alabama)
72 Alabama[edit]
Jacksonville (Jacksonville State University)[2]
83 Alabama[edit]
Livingston (University of West Alabama)[2]
94 Alabama[edit]
Montevallo (University of Montevallo)[2]

我們可以像上面使用for loop來進行清洗,但是pandas提供了更簡單的辦法。我們只需要state name和town name,然後就可以移除所以其他的了。這裡我們可以再次使用pandas的.str()方法,同時我們也可以使用applymap()將一個python callable映射到DataFrame中的每個元素上。

我們一直在使用"元素"這個攝於,但是我們到底是什麼意思呢?看看下面這個"toy"的DataFrame:

1 0 120 Mock Dataset31 Python Pandas42 Real Python53 NumPy Clean

在這個例子中,每個單元 (『Mock』, 『Dataset』, 『Python』, 『Pandas』, etc.) 都是一個元素。因此,applymap()將分別應用一個函數到這些元素上。讓我們定義這個函數。

1>>> def get_citystate(item):2... if ( in item:3... return item[:item.find( ()]4... elif [ in item:5... return item[:item.find([)]6... else:7... return item

pandas的applymap()只用一個參數,就是要應用到每個元素上的函數(callable)。

1>>> towns_df = towns_df.applymap(get_citystate)

首先,我們定義一個函數,它將從DataFrame中獲取每一個元素作為自己的參數。在這個函數中,檢驗元素中是否有一個(或者[

基於上面的檢查,函數返回相應的值。最後,applymap()函數被用在我們的對象上。現在DataFrame就看起來更乾淨了。

1>>> towns_df.head()2 State RegionName30 Alabama Auburn41 Alabama Florence52 Alabama Jacksonville63 Alabama Livingston74 Alabama Montevallo

applymap()方法從DataFrame中提取每個元素,傳遞到函數中,然後覆蓋原來的值。就是這麼簡單!

技術細節:雖然.applymap是一個方便和靈活的方法,但是對於大的數據集它將會花費很長時間運行,因為它需要將python callable應用到每個元素上。一些情況中,使用Cython或者NumPY的矢量化的操作會更高效。

重命名列和移除行

經常的,你處理的數據集會有讓你不太容易理解的列名,或者在頭幾行或最後幾行有一些不重要的信息,例如術語定義,或是附註。

這種情況下,我們想重新命名列和移除一定的行以讓我們只留下正確和有意義的信息。

為了證明我們如何處理它,我們先看一下"olympics.csv"數據集的頭5行:

1$ head -n 5 Datasets/olympics.csv20,1,2,3,4,5,6,7,8,9,10,11,12,13,14,153,? Summer,01 !,02 !,03 !,Total,? Winter,01 !,02 !,03 !,Total,? Games,01 !,02 !,03 !,Combined total4Afghanistan (AFG),13,0,0,2,2,0,0,0,0,0,13,0,0,2,25Algeria (ALG),12,5,2,8,15,3,0,0,0,0,15,5,2,8,156Argentina (ARG),23,18,24,28,70,18,0,0,0,0,41,18,24,28,70

現在我們將它讀入pandas的DataFrame。

1>>> olympics_df = pd.read_csv(Datasets/olympics.csv) 2>>> olympics_df.head() 3 0 1 2 3 4 5 6 7 8 40 NaN ? Summer 01 ! 02 ! 03 ! Total ? Winter 01 ! 02 ! 51 Afghanistan (AFG) 13 0 0 2 2 0 0 0 62 Algeria (ALG) 12 5 2 8 15 3 0 0 73 Argentina (ARG) 23 18 24 28 70 18 0 0 84 Armenia (ARM) 5 1 2 9 12 6 0 0 9 9 10 11 12 13 14 15100 03 ! Total ? Games 01 ! 02 ! 03 ! Combined total111 0 0 13 0 0 2 2122 0 0 15 5 2 8 15133 0 0 41 18 24 28 70144 0 0 11 1 2 9 12

這的確有點亂!列名是以整數的字元串形式索引的,以0開始。本應該是列名的行卻處在olympics_df.iloc[0]。發生這個是因為CSV文件以0, 1, 2, …, 15起始的。

同樣,如果我們去數據集的源文件觀察,上面的NaN真的應該是像"Country"這樣的,? Summer應該代表"Summer Games", 而01 !應該是"Gold"之類的。

因此,我們需要做兩件事:

  • 移除第一行並設置header為第一行
  • 重新命名列

當我們讀CSV文件的時候,可以通過傳遞一些參數到read_csv函數來移除行和設置列名稱。

這個函數有很多可選參數,但是這裡我們只需要header來移除第0行:

1>>> olympics_df = pd.read_csv(Datasets/olympics.csv, header=1) 2>>> olympics_df.head() 3 Unnamed: 0 ? Summer 01 ! 02 ! 03 ! Total ? Winter 40 Afghanistan (AFG) 13 0 0 2 2 0 51 Algeria (ALG) 12 5 2 8 15 3 62 Argentina (ARG) 23 18 24 28 70 18 73 Armenia (ARM) 5 1 2 9 12 6 84 Australasia (ANZ) [ANZ] 2 3 4 5 12 0 9 01 !.1 02 !.1 03 !.1 Total.1 ? Games 01 !.2 02 !.2 03 !.2 100 0 0 0 0 13 0 0 2111 0 0 0 0 15 5 2 8122 0 0 0 0 41 18 24 28133 0 0 0 0 11 1 2 9144 0 0 0 0 2 3 4 515 Combined total160 2171 15182 70193 12204 12

我們現在有了設置為header的正確行,並且所有沒用的行都被移除了。記錄一下pandas是如何將包含國家的列名NaN改變為Unnamed:0的。

為了重命名列,我們將使用DataFrame的rename()方法,允許你以一個映射(這裡是一個字典)重新標記一個軸。

讓我們開始定義一個字典將現有的列名稱(鍵)映射到更多的可用列名稱上(字典的值)。

1>>> new_names = {Unnamed: 0: Country, 2... ? Summer: Summer Olympics, 3... 01 !: Gold, 4... 02 !: Silver, 5... 03 !: Bronze, 6... ? Winter: Winter Olympics, 7... 01 !.1: Gold.1, 8... 02 !.1: Silver.1, 9... 03 !.1: Bronze.1,10... ? Games: # Games,11... 01 !.2: Gold.2,12... 02 !.2: Silver.2,13... 03 !.2: Bronze.2}

我們在對象上調用rename()函數:

1>>> olympics_df.rename(columns=new_names, inplace=True)

設置inplaceTrue可以讓我們的改變直接反映在對象上。讓我們看看是否正確:

1>>> olympics_df.head() 2 Country Summer Olympics Gold Silver Bronze Total 30 Afghanistan (AFG) 13 0 0 2 2 41 Algeria (ALG) 12 5 2 8 15 52 Argentina (ARG) 23 18 24 28 70 63 Armenia (ARM) 5 1 2 9 12 74 Australasia (ANZ) [ANZ] 2 3 4 5 12 8 Winter Olympics Gold.1 Silver.1 Bronze.1 Total.1 # Games Gold.2 90 0 0 0 0 0 13 0101 3 0 0 0 0 15 5112 18 0 0 0 0 41 18123 6 0 0 0 0 11 1134 0 0 0 0 0 2 314 Silver.2 Bronze.2 Combined total150 0 2 2161 2 8 15172 24 28 70183 2 9 12194 4 5 12

Python數據清洗:回顧

這個教程中,你學會了從數據集中如何使用drop()函數去除不必要的信息,也學會了如何為數據集設置索引,以讓items可以被容易的找到。

更多的,你學會了如何使用.str()清洗對象欄位,以及如何使用applymap對整個數據集清洗。最後,我們探索了如何移除CSV文件的行,並且使用rename()方法重命名列。

掌握數據清洗非常重要,因為它是數據科學的一個大的部分。你現在應該有了一個如何使用pandas和numpy進行數據清洗的基本理解了。更多內容可參考pandas和numpy官網。

realpython.com/python-d

關注微信公眾號Python數據科學,帶你走進數據的世界。

推薦閱讀:

Pandas學習-6concat合併
【翻譯】《利用Python進行數據分析·第2版》第5章(中)pandas入門
Pandas學習-8pandas plot圖表
將Numpy datetime64類型日期進行格式轉換
如何與pandas愉快地玩耍(一)

TAG:Python | 數據清洗 | pandas包 |