1. 程式人生 > >《利用Python進行資料分析·第2版》第7章 資料清洗和準備

《利用Python進行資料分析·第2版》第7章 資料清洗和準備

在資料分析和建模的過程中,相當多的時間要用在資料準備上:載入、清理、轉換以及重塑。這些工作會佔到分析師時間的 80% 或更多。有時,儲存在檔案和資料庫中的資料的格式不適合某個特定的任務。許多研究者都選擇使用通用程式語言(如 Python、Perl、R 或 Java)或 UNIX 文字處理工具(如 sed 或 awk)對資料格式進行專門處理。幸運的是,pandas 和內建的 Python 標準庫提供了一組高階的、靈活的、快速的工具,可以讓你輕鬆地將資料規變為想要的格式。

如果你發現了一種本書或 pandas 庫中沒有的資料操作方式,請儘管在郵件列表或 GitHub 網站上提出。實際上,pandas 的許多設計和實現都是由真實應用的需求所驅動的。

在本章中,我會討論處理缺失資料、重複資料、字串操作和其它分析資料轉換的工具。下一章,我會關注於用多種方法合併、重塑資料集。

7.1 處理缺失資料

在許多資料分析工作中,缺失資料是經常發生的。pandas 的目標之一就是儘量輕鬆地處理缺失資料。例如,pandas 物件的所有描述性統計預設都不包括缺失資料。

缺失資料在 pandas 中呈現的方式有些不完美,但對於大多數使用者可以保證功能正常。對於數值資料,pandas 使用浮點值 NaN(Not a Number)表示缺失資料。我們稱其為哨兵值,可以方便的檢測出來:

In [10]: string_data = pd.Series(['aardvark', 'artichoke'
, np.nan, 'avocado']) In [11]: string_data Out[11]: 0 aardvark 1 artichoke 2 NaN 3 avocado dtype: object In [12]: string_data.isnull() Out[12]: 0 False 1 False 2 True 3 False dtype: bool

在 pandas 中,我們採用了 R 語言中的慣用法,即將缺失值表示為 NA,它表示不可用 not available。在統計應用中,NA 資料可能是不存在的資料或者雖然存在,但是沒有觀察到(例如,資料採集中發生了問題)。當進行資料清洗以進行分析時,最好直接對缺失資料進行分析,以判斷資料採集的問題或缺失資料可能導致的偏差。

Python 內建的 None 值在物件陣列中也可以作為 NA:

In [13]: string_data[0] = None

In [14]: string_data.isnull()
Out[14]: 
0     True
1    False
2     True
3    False
dtype: bool

pandas 專案中還在不斷優化內部細節以更好處理缺失資料,像使用者 API 功能,例如 pandas.isnull,去除了許多惱人的細節。表 7-1 列出了一些關於缺失資料處理的函式。

濾除缺失資料

過濾掉缺失資料的辦法有很多種。你可以通過 pandas.isnull 或布林索引的手工方法,但 dropna 可能會更實用一些。對於一個 Series,dropna 返回一個僅含非空資料和索引值的 Series:

In [15]: from numpy import nan as NA

In [16]: data = pd.Series([1, NA, 3.5, NA, 7])

In [17]: data.dropna()
Out[17]: 
0    1.0
2    3.5
4    7.0
dtype: float64

這等價於:

In [18]: data[data.notnull()]
Out[18]: 
0    1.0
2    3.5
4    7.0
dtype: float64

而對於 DataFrame 物件,事情就有點複雜了。你可能希望丟棄全 NA 或含有 NA 的行或列。dropna 預設丟棄任何含有缺失值的行:

In [19]: data = pd.DataFrame([[1., 6.5, 3.], [1., NA, NA],
   ....:                      [NA, NA, NA], [NA, 6.5, 3.]])

In [20]: cleaned = data.dropna()

In [21]: data
Out[21]: 
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0

In [22]: cleaned
Out[22]: 
     0    1    2
0  1.0  6.5  3.0

傳入 how='all'將只丟棄全為 NA 的那些行:

In [23]: data.dropna(how='all')
Out[23]: 
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
3  NaN  6.5  3.0

用這種方式丟棄列,只需傳入 axis=1 即可:

In [24]: data[4] = NA

In [25]: data
Out[25]: 
     0    1    2   4
0  1.0  6.5  3.0 NaN
1  1.0  NaN  NaN NaN
2  NaN  NaN  NaN NaN
3  NaN  6.5  3.0 NaN

In [26]: data.dropna(axis=1, how='all')
Out[26]: 
     0    1    2
0  1.0  6.5  3.0
1  1.0  NaN  NaN
2  NaN  NaN  NaN
3  NaN  6.5  3.0

另一個濾除 DataFrame 行的問題涉及時間序列資料。假設你只想留下一部分觀測資料,可以用 thresh 引數實現此目的:

In [27]: df = pd.DataFrame(np.random.randn(7, 3))

In [28]: df.iloc[:4, 1] = NA

In [29]: df.iloc[:2, 2] = NA

In [30]: df
Out[30]: 
          0         1         2
0 -0.204708       NaN       NaN
1 -0.555730       NaN       NaN
2  0.092908       NaN  0.769023
3  1.246435       NaN -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741

In [31]: df.dropna()
Out[31]: 
          0         1         2
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741

In [32]: df.dropna(thresh=2)
Out[32]: 
          0         1         2
2  0.092908       NaN  0.769023
3  1.246435       NaN -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741

填充缺失資料

你可能不想濾除缺失資料(有可能會丟棄跟它有關的其他資料),而是希望通過其他方式填補那些 “空洞”。對於大多數情況而言,fillna 方法是最主要的函式。通過一個常數呼叫 fillna 就會將缺失值替換為那個常數值:

In [33]: df.fillna(0)
Out[33]: 
          0         1         2
0 -0.204708  0.000000  0.000000
1 -0.555730  0.000000  0.000000
2  0.092908  0.000000  0.769023
3  1.246435  0.000000 -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741

若是通過一個字典呼叫 fillna,就可以實現對不同的列填充不同的值:

In [34]: df.fillna({1: 0.5, 2: 0})
Out[34]: 
          0         1         2
0 -0.204708  0.500000  0.000000
1 -0.555730  0.500000  0.000000
2  0.092908  0.500000  0.769023
3  1.246435  0.500000 -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741

fillna 預設會返回新物件,但也可以對現有物件進行就地修改:

In [35]: _ = df.fillna(0, inplace=True)

In [36]: df
Out[36]: 
          0         1         2
0 -0.204708  0.000000  0.000000
1 -0.555730  0.000000  0.000000
2  0.092908  0.000000  0.769023
3  1.246435  0.000000 -1.296221
4  0.274992  0.228913  1.352917
5  0.886429 -2.001637 -0.371843
6  1.669025 -0.438570 -0.539741

對 reindexing 有效的那些插值方法也可用於 fillna:

In [37]: df = pd.DataFrame(np.random.randn(6, 3))

In [38]: df.iloc[2:, 1] = NA

In [39]: df.iloc[4:, 2] = NA

In [40]: df
Out[40]: 
          0         1         2
0  0.476985  3.248944 -1.021228
1 -0.577087  0.124121  0.302614
2  0.523772       NaN  1.343810
3 -0.713544       NaN -2.370232
4 -1.860761       NaN       NaN
5 -1.265934       NaN       NaN

In [41]: df.fillna(method='ffill')
Out[41]: 
          0         1         2
0  0.476985  3.248944 -1.021228
1 -0.577087  0.124121  0.302614
2  0.523772  0.124121  1.343810
3 -0.713544  0.124121 -2.370232
4 -1.860761  0.124121 -2.370232
5 -1.265934  0.124121 -2.370232

In [42]: df.fillna(method='ffill', limit=2)
Out[42]: 
          0         1         2
0  0.476985  3.248944 -1.021228
1 -0.577087  0.124121  0.302614
2  0.523772  0.124121  1.343810
3 -0.713544  0.124121 -2.370232
4 -1.860761       NaN -2.370232
5 -1.265934       NaN -2.370232

只要有些創新,你就可以利用 fillna 實現許多別的功能。比如說,你可以傳入 Series 的平均值或中位數:

In [43]: data = pd.Series([1., NA, 3.5, NA, 7])

In [44]: data.fillna(data.mean())
Out[44]: 
0    1.000000
1    3.833333
2    3.500000
3    3.833333
4    7.000000
dtype: float64

表 7-2 列出了 fillna 的參考。

7.2 資料轉換

本章到目前為止介紹的都是資料的重排。另一類重要操作則是過濾、清理以及其他的轉換工作。

移除重複資料

DataFrame 中出現重複行有多種原因。下面就是一個例子:

In [45]: data = pd.DataFrame({'k1': ['one', 'two'] * 3 + ['two'],
   ....:                      'k2': [1, 1, 2, 3, 3, 4, 4]})

In [46]: data
Out[46]: 
    k1  k2
0  one   1
1  two   1
2  one   2
3  two   3
4  one   3
5  two   4
6  two   4

DataFrame 的 duplicated 方法返回一個布林型 Series,表示各行是否是重複行(前面出現過的行):

In [47]: data.duplicated()
Out[47]: 
0    False
1    False
2    False
3    False
4    False
5    False
6     True
dtype: bool

還有一個與此相關的 drop_duplicates 方法,它會返回一個 DataFrame,重複的陣列會標為 False:

In [48]: data.drop_duplicates()
Out[48]: 
    k1  k2
0  one   1
1  two   1
2  one   2
3  two   3
4  one   3
5  two   4

這兩個方法預設會判斷全部列,你也可以指定部分列進行重複項判斷。假設我們還有一列值,且只希望根據 k1 列過濾重複項:

In [49]: data['v1'] = range(7)

In [50]: data.drop_duplicates(['k1'])
Out[50]: 
    k1  k2  v1
0  one   1   0
1  two   1   1

duplicated 和 drop_duplicates 預設保留的是第一個出現的值組合。傳入 keep='last'則保留最後一個:

In [51]: data.drop_duplicates(['k1', 'k2'], keep='last')
Out[51]: 
    k1  k2  v1
0  one   1   0
1  two   1   1
2  one   2   2
3  two   3   3
4  one   3   4
6  two   4   6

利用函式或對映進行資料轉換

對於許多資料集,你可能希望根據陣列、Series 或 DataFrame 列中的值來實現轉換工作。我們來看看下面這組有關肉類的資料:

In [52]: data = pd.DataFrame({'food': ['bacon', 'pulled pork', 'bacon',
   ....:                               'Pastrami', 'corned beef', 'Bacon',
   ....:                               'pastrami', 'honey ham', 'nova lox'],
   ....:                      'ounces': [4, 3, 12, 6, 7.5, 8, 3, 5, 6]})

In [53]: data
Out[53]: 
          food  ounces
0        bacon     4.0
1  pulled pork     3.0
2        bacon    12.0
3     Pastrami     6.0
4  corned beef     7.5
5        Bacon     8.0
6     pastrami     3.0
7    honey ham     5.0
8     nova lox     
            
           

相關推薦

利用Python進行資料分析》第二,第二精選筆記

因為這本書是專注於Python資料處理的,對於一些Python的資料結構和庫的特性難免不足。因此,本章和第3章的內容只夠你能學習本書後面的內容。 在我來看,沒有必要為了資料分析而去精通Python。我鼓勵你使用IPython shell和Jupyter試驗示例

《計算機演算法設計與分析 2+3+4 (王曉東) 》原書附答案pdf電子書附下載連結+30個總結JVM虛擬機器的技術文排版好(收藏版)

技術書閱讀方法論 一.速讀一遍(最好在1~2天內完成) 人的大腦記憶力有限,在一天內快速看完一本書會在大腦裡留下深刻印象,對於之後複習以及總結都會有特別好的作用。 對於每一章的知識,先閱讀標題,弄懂大概講的是什麼主題,再去快速看一遍,不懂也沒有關係,但是一定要在不懂的

JavaScript DOM程式設計藝術(2)第二 語法

一.變數 把值存在變數的操作——賦值 JavaScript可以直接對變數賦值而不需事先宣告。 如果在對某個變數賦值前沒有宣告,賦值操作會自動宣告該變數。var age; JavaScript中變數不能包含空格或標點符號 變數可以使用駝峰命名 二.資料型別 1.必須明確型別宣告

算法競賽入門經典2 1

計算 const 解決問題 pause 會有 return 數學 getchar() scanf 學習目標:   熟悉C語言程序的編譯和運行   學會編程計算並輸出常見的算術表達式的結果   掌握整數和浮點數的含義和輸出方法、聲明方法、讀入方法   掌握數學函數的使用方法

演算法競賽入門經典2 2 迴圈結構

學習目標   掌握for迴圈、while迴圈、do-while迴圈的使用方法   學會使用計數器和累加器   學會用輸出中間結果的方法除錯   學會用計時函式測試程式效率   學會用重定向、fopen的方式讀寫檔案   瞭解演算法競賽對檔案讀寫方式和命名的嚴格性   記住變數在賦值之前的值是不確

《演算法競賽入門經典》(2)第二習題

本文部分習題參考了litiouslove的blog: http://blog.csdn.net/litiouslove/article/details/7891700 習題2-1 水仙花數(daffodil) 輸出100~999中的所有水仙花數。若3位數ABC滿足ABC=A3+B3+

《演算法競賽入門經典》(2)第一 部分實驗題

1.5.2資料型別實驗 實驗A1:表示式11111*11111的值是多少?把5個1改成6個1呢?9個1呢? 實驗A2:把實驗A1中的所有數換成浮點數,結果如何? 實驗A3:表示式sqrt(-10)的值是多少?嘗試用各種方式輸出。在計算的過程中系統會報錯嗎? 實驗A4:表示式1.0/

[刷題]演算法競賽入門經典(2) 4-7/UVa509

//UVa509 - RAID! #include<iostream> int d, s, b, t, times = 0; char disk_data[7][6666], type; inline char* disk(int x, i

資料分析(入門篇)-第一-資料分析那些事兒

《誰說菜鳥不會資料分析》這本書,看起來是本給小白看的書,實則內容豐富,值得認真學習。 從今天開始,看第三遍,順便寫個讀書筆記,備忘。 資料分析型別:描述性資料分析、探索性資料分析、驗證性資料分析 資料分析作用:現狀分析、原因分析、預測分析 資料分析六步曲:明確分析目的和思

資料基礎---《利用Python進行資料分析·212 pandas高階應用

之前自己對於numpy和pandas是要用的時候東學一點西一點,直到看到《利用Python進行資料分析·第2版》,覺得只看這一篇就夠了。非常感謝原博主的翻譯和分享。 前面的章節關注於不同型別的資料規整流程和NumPy、pandas與其它庫的特點。隨著時間的發展,pandas發展出了更多適

資料基礎---《利用Python進行資料分析·26 資料載入、儲存與檔案格式

之前自己對於numpy和pandas是要用的時候東學一點西一點,直到看到《利用Python進行資料分析·第2版》,覺得只看這一篇就夠了。非常感謝原博主的翻譯和分享。 訪問資料是使用本書所介紹的這些工具的第一步。我會著重介紹pandas的資料輸入與輸出,雖然別的庫中也有不少以此為目的的工具

資料基礎---《利用Python進行資料分析·24 NumPy基礎:陣列向量計算

之前自己對於numpy和pandas是要用的時候東學一點西一點,直到看到《利用Python進行資料分析·第2版》,覺得只看這一篇就夠了。非常感謝原博主的翻譯和分享。 NumPy(Numerical Python的簡稱)是Python數值計算最重要的基礎包。大多數提供科學計算的包都是用Nu

資料基礎---《利用Python進行資料分析·211 時間序列

之前自己對於numpy和pandas是要用的時候東學一點西一點,直到看到《利用Python進行資料分析·第2版》,覺得只看這一篇就夠了。非常感謝原博主的翻譯和分享。 時間序列(time series)資料是一種重要的結構化資料形式,應用於多個領域,包括金融學、經濟學、生態學、神經科學、物

資料基礎---《利用Python進行資料分析·210 資料聚合與分組運算

之前自己對於numpy和pandas是要用的時候東學一點西一點,直到看到《利用Python進行資料分析·第2版》,覺得只看這一篇就夠了。非常感謝原博主的翻譯和分享。 對資料集進行分組並對各組應用一個函式(無論是聚合還是轉換),通常是資料分析工作中的重要環節。在將資料集載入、融合、準備好之

資料基礎---《利用Python進行資料分析·28 資料規整:聚合、合併重塑

之前自己對於numpy和pandas是要用的時候東學一點西一點,直到看到《利用Python進行資料分析·第2版》,覺得只看這一篇就夠了。非常感謝原博主的翻譯和分享。 在許多應用中,資料可能分散在許多檔案或資料庫中,儲存的形式也不利於分析。本章關注可以聚合、合併、重塑資料的方法。 首先

資料基礎---《利用Python進行資料分析·27 資料清洗準備

之前自己對於numpy和pandas是要用的時候東學一點西一點,直到看到《利用Python進行資料分析·第2版》,覺得只看這一篇就夠了。非常感謝原博主的翻譯和分享。 在資料分析和建模的過程中,相當多的時間要用在資料準備上:載入、清理、轉換以及重塑。這些工作會佔到分析師時間的80%或更多。

資料基礎---《利用Python進行資料分析·25 pandas入門

之前自己對於numpy和pandas是要用的時候東學一點西一點,直到看到《利用Python進行資料分析·第2版》,覺得只看這一篇就夠了。非常感謝原博主的翻譯和分享。 pandas是本書後續內容的首選庫。它含有使資料清洗和分析工作變得更快更簡單的資料結構和操作工具。pandas經常和其它工

➢《利用Python進行資料分析》(原書2)|書籍分享

《利用Python進行資料分析》(原書第2版) 英: Python for Data Analysis: Data Wrangling with Pand 適讀人群 :適合剛學Python的資料分析師或剛學資料科學以及科學計算的Python程式設計者。 閱

初入資料分析2(《利用Python進行資料分析·2》筆記)

初入資料分析2 遍歷 seq=[(1,2,3),(4,5,6),(7,8,9)] for a,b,c in seq: print("a==",a,"b==",b,"c==",c) a== 1 b== 2 c== 3 a== 4 b== 5 c== 6 a==

利用Python進行資料分析·27 資料清洗準備

在資料分析和建模的過程中,相當多的時間要用在資料準備上:載入、清理、轉換以及重塑。這些工作會佔到分析師時間的 80% 或更多。有時,儲存在檔案和資料庫中的資料的格式不適合某個特定的任務。許多研究者都選擇使用通用程式語言(如 Python、Perl、R 或 Java)或 UNI