用Python進行數據分析的基礎姿勢(一)

用Python進行數據分析的基礎姿勢(一)

版權聲明

本文首發於微信公眾號

沁機邁可思(zw_life-long_doing)

無需授權即可轉載

轉載時請註明出處


如同我們做其他事情一樣,數據分析也是有一定流程的。它一般分為四步:

確定問題->分解問題和數據->評估數據->作出決策

確定問題很好理解,就是確定方向。因為只有當我們先清楚自己處理這一大堆數據的目的是什麼,才能指導我們快速向前,否則就像一隻沒有目的得蒼蠅一樣,在數據里來回兜圈。

一般來說,我們確定問題的對象是我們的「客戶」。他可能是你的上司,也可能是公司的業務部門,甚至可能是你自己。當我們對問題有什麼疑問的時候,一定要跟自己的「客戶」對接到位,可不要自己想當然的理解。

在確定了問題之後,我們要做的,就是分解問題和數據。到這一步,你可能會問,知道了問題是什麼,有了數據,不應該著實開始處理數據嗎,為什麼還要分解一遍?

和確定問題的邏輯差不多。我們得大量的數據裡面,提取出與問題相關的數據,進行處理和分析,以達到效率的最大化。因此,我認為這也是數據分析師在拿到原始數據的時候,應有的一種意識,也可以說成是理解數據

但同時,我們也不要忘了要分解問題。因為在大多數的情況下,一個大的問題,解決起來往往是比較困難的,也是相對複雜的。那麼,這個時候我們就可以把大的問題分解成一個個相關的小問題,再逐一突破,畢竟小問題處理起來更簡單一些嘛。當這些小問題有了答案之後,那大問題的答案自然而然就有了。

接下來,就是評估數據了。在這裡面,有兩個方面需要注意。一個是對分解出來的數據,進行預處理,以適合我們操作習慣;另一個則是對這些數據進行深入的挖掘和分析,形成自己的判斷。

最後一步,就是作出自己的決策,以報告的形式向「客戶」輸出我們判斷,讓它產生價值。在這一步裡面,數據可視化是很常用的一個工具。

可以說,在我們每一次的數據分析中,都少不了這四步流程。但是,當我們使用Python進行數據分析的時候,仍有很多和平時不一樣的地方。本文就先從數據分析包的選擇、數據清洗這兩個方面來談談「用Python進行數據分析的基礎姿勢」。

數據分析包的選擇

我們選擇數據分析包的目的很簡單,無非為了更好更快的理解數據。所以,在這之前,我們需要了解用Python進行數據分析的兩個常用包:Numpy與Pandas

  • Numpy包

Numpy是一個高性能科學計算和數據分析的基礎包。這個包本身並沒有提供多麼高級的數據分析功能,但是理解Numpy數組以及面向數組的計算將有助於我們更高效的使用Pandas之類的工具

說到Numpy包,它最重要的一個特點就是其N維數組對象(即ndarray)。可以理解它是一個大數據集容器,我們可以利用這種數組對整塊數據執行一些數學運算。

既然是數組,那麼就涉及到怎麼創建一個數組。在Numpy包里,無論是創建一個一維數組還是多維數組,都是array函數。

因為ndarray是一個通用的同構數據多維容器,因為其中的所有元素必須是同一類型。其中的每個數組都可以用shape函數來表示各維度大小,用dtype來說明數組是哪類數據類型。

這裡說說數值型dtype的命名方式:一個類型名,後面跟一個用於表示各元素位長的的數字。比如上圖中的float64,前面的float表示Python中的浮點型,後面的「64」表示這個對象需要佔用8位元組(即64位)的位長。

一般情況下,我們除了用dtype函數查看數組的數據類型外,也可能遇見更改它數據類型的情況。這個時候我們就要用到astype函數,下圖我們更改一下arr1的數據類型。

發現了嗎?當我們更改了數組的數據類型之後,它表示的值也會相應的發生改變。比如上圖中,我們更改之前的float64int64,原來arr1數組中元素的小數位就被砍掉了。

在Numpy中,數組的索引算得上是一個很豐富的內容,而且在對數組進行計算的時候,也可能會用到這個功能,尤其在多維數組中。

一維數組比較簡單,它和列表類型的功能差不多。我們重新定義一個一維數組來說明一下。

但對於一個高維數組而言,各索引位置上的元素不再是標量,而是一個數組,而且花樣更多。

在高維數組中的,需要注意的是:「只有冒號,沒有數字」表示選取整個行(或列)的數據

講了索引,那接下來講講數組中的運算。在數組的運算中,對某數組進行算術運算,甚至是與大小相等的數組進行任何算術運算,都會逐個對所有元素進行運算。這在一維數組與高維數組中並沒有什麼差別。因此,這裡就只拿一維數組舉例。

但是在進行數據分析的時候,我們不一定需要所有的元素統計計算,可能只需要行,或者列的計算結果。這個時候,就需要用到一個參數axis在高維數組中,若axis = 1,它代表所有行的數據;若axis = 0,它代表所有列的數據。

也正是由於Numpy在運算時的會遍歷所有元素的特性,我們可以將許多種數據處理任務表述為簡潔的數組表達式。這種用數組來代替循環的做法,通常被稱為矢量化。

一般來說,矢量化數組運算會比等價的純Python方式快上一兩個數量級,尤其是各種數值計算。比如說,一隻蝸牛,從0開始隨機的向前(步長1)或者後退(步長-1)行走,步長1與-1出現的概率相等。我們可以怎麼來實現呢?

  • 純Python的方法,即用到循環。

  • 矢量化數組計算的方法。

相信細心的你,一定發現了:通過純Python用循環的方式,得到的結果是列表類型,需要進一步的轉換為數組才能進行最大值、最小值或是其他的統計計算。而矢量化的數組計算的運算結果,直接就是數組了,方便很多。而且實現的步驟也比純Python要短不少。

當然,這也僅僅最簡單的利用數組來處理數據,但更高階的內容在本文不做涉及。

  • Pandas包

Pandas是基於Numpy構建的,含有使數據分析工作變得更快更簡單的高級數據結構和操作工具。它有兩個主要的數據結構,一個是「Series」,一種類似於一維數組的對象;另一個是「DataFrame」,是一種表格型的數據結構。

先來說說Series,它是有一組數據以及一組與之相關的數據標籤(即索引)組成,僅有一組數據就可以產生最簡單的Series數據表。

Series字元串的表現形式為:索引在左邊,值在右邊。如果我們沒有為數據指定索引的話,那它就會自動的創建一個0到N-1的索引。也就是說,我們可以自定義索引。

與Numpy數組中選取數據的方式不同。在Series表中,我們除了按照位置選取以外,還可以通過它的索引來選取對應的單個或一組值。

回憶一下,按照索引來選取對應值的數據類型,還有哪一個,字典是不是也是這樣的過程呢?換句話,我們是不是可以通過一個字典,來建立一個Series表呢?事實證明是可以的哈,因為它也是索引值到數據值的一個映射嘛。

和Numpy的數組一樣,Series表也可以進行向量化運算。不同的是,Numpy的數組必須是等量步長的數組才能進行向量化運算,而Series在運算中會自動對齊不同索引的數據。

上圖中,因為在c表中沒有對應索引「b」的值,所以b表與c表相加後,會出現缺失值「NaN」的情況。至於怎麼處理缺失值,我放在DataFrame中來介紹。

關於Series表的基本知識,上面就講的就差不多了。接下來講一講DataFrame(數據框)的基礎知識。

DataFrame是一個以二維結構保存數據的表格型數據結構,它既有行索引也有列索引,可以被看做是由多個Series組成的字典。但與Numpy高維數組中需要統一數據類型的情況不同,DataFrame中允許有不同數據類型存在,每列的值可以是字元串,也可以是布爾值。

這個特性也說明了我們在處理高級數據的時候,會更多的用到DataFrame這個數據結構。

構建DataFrame的方法有很多,比較常用的是直接傳入一個有等長列表或Numpy數組組成的字典,另一種常見的形式是嵌套字典。

在DataFrame中,我們有四種方法來獲取自己想要的值。

在這四種方式裡面,我建議用loc函數通過索引來選取你想要的值,因為某個表的索引是很清晰的,通過索引來選取數據一般不會出什麼岔子。而且在很多時候,我們選取數據的時候不會選取單個數據,通常是選取多行多列的數據,這個時候怎麼辦呢?

同時,我們也可以設計一個條件來選取數據。

下圖表格總結了可以輸入給DataFrame數據框的數據結構。

最後,講一講在Series與DataFrame中的數據的基本手段。

  • 重新索引

在重新索引功能中,pandas對象的一個重要方法是reindex。這裡要注意是,對於DataFrame來說,reindex可以修改索引和列中的其中一個,或者兩個都修改。

下圖總結一下在reindex函數涉及到的一些參數。

  • 排序

根據條件對數據集進行排序也是一種重要的內置運算。如果我們要對任意軸上的的索引(或值)進行排序,可使用sort_index(或sort_values)的方法。

  • 處理缺失數據

pandas使用浮點值「NaN」表示浮點和非浮點數組中的缺失數據。在面對缺失值的時候,我們通常有兩種處理方法:刪除和填充

過濾掉缺失數據的方法有很多,但這裡面,使用「dropna」函數會比較實用一些。在Series表中,因為只有一列數值,所以dropna會直接刪除這一列里的所有缺失值。但對於DataFrame對象來說,就不是這麼簡單了。因為你可能希望濾掉所有的缺失值,也可能希望僅濾掉含有缺失值的行或列。

在使用dropna函數的時候,通常它有個參數how。若how=all表示刪除全部為缺失值的某行/列;若how=any表示刪除任一含有缺失值的某行/列;使用thresh則指定對象中至少需要包含多少個控制才會被刪除等等。

當然,我們處理刪除缺失值以外,還可以對它進行填充動作。大多數情況下,我們使用「fillna」函數來解決。

  • 匯總和計算描述統計

在利用Python處理數據的時候,我們難免會遇見求和或者求均值的情況。理論上來說,這裡是比較簡單的。但是有一個知識點,需要詳細說明一下。也就是axis這個參數在DataFrame中的指向問題。先來看一個例子。

注意看紅框圈出來的地方。在我們要刪除某一列的時候,使用的是「axis=1」,但是當我們在計算每一行均值的時候,也是使用的「axis=1」,為什麼同一個語句,會出現兩個不同的使用場景呢?

開始的時候我也是蒙的。但是換個思路,就清晰了:axis=1,指的是沿著行求所有列的平均值,代表了橫軸;而axis=0,則是沿著列求所有行的平均值,代表了縱軸。而,drop語句,就是沿著one這一列的方向,刪除掉所有行的數據,所有axis=1。看了下面的圖,我相信你更清晰一些。

最後總結一下我們在處理數據的時候,可能會用到的描述和匯總統計語句。

以上便是Numpy與Pandas包的基本運用,接下來就結合上面的知識講一講我們在進行數據清洗的時候需要走哪些流程。

數據清洗

在我們進行數據分析的過程中,可以說有60%的時間是花在了數據清洗上的,比如說處理缺失值,刪除異常值等等。我們進行數據預處理的目標,是把數據改變成我們喜歡的樣子,方便後面對他進行深入的分析。

一般來說,我們進行數據清洗的步驟可以分為六步,分別是選擇子集->列表重命名->缺失數據處理->數據類型轉換->數據排序->異常值處理。

我們先導入一個「豆瓣熱門電影.xlsx」數據表。

然後再通過選擇子集的方式,來選取我們想要的行和列,並看看現在數據表的基本信息。

這裡我選擇的事剔除掉編劇、主演等列,因為這些列的數據對我們了解豆瓣整個熱門電影榜單來說,並不那麼重要。所以我用了drop函數來刪除掉我不要的列,重新賦值給了文件films_df

接下來對列表進行重命名操作,比如將上映年份重新命名為上映時間。這裡用到的是rename函數,並引入了一個inplace參數,目的是告訴計算機這個更改是否在原表上進行,而不用新建一個副本。inplace=False表示著新建一個副本,這個參數默認是True

但是在處理缺失數據的時候,我們需要吹到這個表裡面是否有缺失數據。這個時候有兩種方式,一個是用isnull或者notnull函數判定表中是否含有缺失值數據,結果返回一個布爾值,然後用條件判斷這表裡是否有False的情況。這個語句會比較清晰,但是我個人覺得在效率上會有一點麻煩,因為要寫兩次代碼。所以,這裡我就用count函數來計算所有列的非空值的數量。因為我們知道整張表有280行,如果哪一列低於了這個值,就說明這裡有缺失值。

接下來就是轉換數據類型,因為我們在導入數據表的時候,為了避免數據顯示有誤,所以統一導入的事字元串類型。但是字元串類型是不能進行計算的,所以我們需要把部分數據轉換成我們需要的整形或者浮點型。即把「上映時間」這列改為日期格式,將評分評價人數這兩列分別改成浮點型和整形

這時,要用到astypeto_datetime函數了。但是這裡要注意兩點:

  • 在DataFrame中,如果我們要更改某列的數據列,我們需要把這一列選取出來再替換,最後賦值到對應的地方。
  • format參數表示的是原數據表中的時間格式。因為原數據表中只有年,因此這裡是format=『&Y』

同時,我們看到片長這列的數據類型仍然是字元串類型。但由於它的值是數字和字元串的組合,所以我們不能進行簡單的改變,需要先將它們分割開來。因此,我考慮用split()函數通過分隔符的方式對字元串進行簡單切片。

但也正如我們演示的那樣,通過split分割後的字元串是一個列表類型,如果我們需要對列表進行統計操作的話,就需要將這個列表生成數組才能進行計算。所以,我們需要定義一個循環函數,將分割後的列表數據生成一個數組。然後修改數據表中的值,最後批量賦值修改。

在對數據類型進行了轉換之後,我們需要將這個數據表按照我們自己想要看到結果進行排序。這裡呢,我們就按照評分這一欄對這個數據表進行重排。

最後,我們來看看在這些電影裡面,是否有沒有人評價的情況。如果有的話,就把它踢掉。

以上,便是我們在拿到原始數據的時候,需要將它進行預處理的全部過程。拿著這份我們預處理後的數據,我們可以知道它的基本描述統計信息,了解在279部豆瓣的熱門電影中,平均評分是6.63分等信息。

照理說,在用Python進行數據分析的時候,數據可視化是很基礎也是很重要的一步。但是這裡因為篇幅限制,就不再講解了。之後我會另寫一篇關於數據可視化的文章,有需要的夥伴可以掃描文末的二維碼關注我的微信公眾號。

我叫鍾小韋,愛折騰的天府小生,在自我超越的路上,期待與你同行。

weixin.qq.com/r/ADhaQob (二維碼自動識別)


推薦閱讀:

【手撕版】MXNet應用之線性回歸
0019數據處理:數據計算之加減乘除和平均數
分享一個基於深度學習神經網路做的一個分類器
手游線上運營流程規範之數據分析
數據分析的三板斧

TAG:數據分析 | 數據挖掘 | Python |