Python 神兵譜之數據分析-中篇:數據處理

前言

承接上篇《Python 神兵譜之數據分析-上篇:數據採集》,今天咱們來說講這中篇:數據處理。html

若是說數據採集比如戰前情報收集、戰略部署,那麼,數據處理比如短兵相接、浴血廝殺了。俗話說,一將功成萬骨枯,戰鬥勝利後風光無限的是一軍之將,以命相博的將士每每卻默默無聞。git

數據處理也是如此,風光背後,是一位位數據處理工程師默默的付出,他們劈荊斬棘,他們乘風破浪。沒人知道他們剔除了多少髒數據,沒人知道他們變換了多少數據模型,咱們看到的只是展現給咱們的冰山一角的數據而已。github

中篇:數據處理

說到數據處理,最大名鼎鼎的應該就是「Excel」了,它的大名,可謂無人不知,無人不曉。有了 Excel,即便毫無編程經驗的人,都能對數據耍上兩把。而咱們今天就來看看,僅僅一點點代碼,就能實現的更爲強大的功能。算法

Numpy

第一把交椅,必須是「Numpy」了。很多人可能據說過,可是可能從未用過,由於 Numpy 是 Python 數據處理的基石,是其餘很多相關工具的依賴。編程

Numpy 的功能很是純粹,它爲 Python 提供了一個很是強大且靈活的「數組」數據結構。api

可是 Python 不是有列表(list)了嗎?爲何還要其餘的「數組」結構?數組

Numpy 主要有如下幾個特色:bash

  • list 僅僅是一個「鏈表」,而 Numpy 提供了真正的多維數組
  • 提供了衆多的數組相關操做
  • 提供了許多線性代數等數學函數
  • 提供了廣播功能,像操做標量同樣操做多維數組
  • 底層使用 C 實現,很是快,適合大量數據處理

Numpy 提供了很是方便的方法生成多維數組,例如從 list 轉換而來。數據結構

import numpy as np

a = np.array([1,2,3,4])
複製代碼

第一行引入 Numpy,這是通常推薦的作法,用 as 別名爲 np。不是必須的,但建議遵循。app

還有衆多的生成函數。

# 生成一個 3 * 4 的矩陣,每一個元素都是 0
np.zeros((3,4))
# 生成一個 2 * 3 的矩陣,每一個元素都是 1
np.ones( (2,3) )
# 等差數列生成,從 10 到 30,5 遞增
np.arange(10, 30, 5)
複製代碼

不一樣於 list,數組的每一個元素必須有一致的數據類型。

>>> a.dtype.name
'int64'
複製代碼

能夠在建立時經過 dtype 參數指定,例如 int32,int64,float64 等。

Numpy 的數組有幾個比較重要的屬性。

  • ndim:軸的數量,也就是維度
  • shape:數組大小的元祖
  • size:總數據個數
  • dtype:數據類型
  • itemsize:每一個數組元素佔的字節數
# 建立一個 1 到 14 到數組,並改爲 3 * 5 的矩陣
>>> a = np.arange(15).reshape(3, 5)
>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
>>> a.ndim
2
>>> a.shape
(3, 5)
>>> a.size
15
>>> a.dtype.name
'int64'
>>> a.itemsize
8
複製代碼

這仍是牛刀小試,讓咱們來見識 Numpy 的實力吧,像操做普通標量同樣操做數組。

# 數組每一個元素乘以 2
>>> b = a * 2
>>> b
array([[ 0,  2,  4,  6,  8],
       [10, 12, 14, 16, 18],
       [20, 22, 24, 26, 28]])
# 數組對應元素相加
>>> a + b
array([[ 0,  3,  6,  9, 12],
       [15, 18, 21, 24, 27],
       [30, 33, 36, 39, 42]])
# 數組對應元素相乘
>>> a * b
array([[  0,   2,   8,  18,  32],
       [ 50,  72,  98, 128, 162],
       [200, 242, 288, 338, 392]])
# 邏輯判斷,每一個元素是否小於 8
>>> a < 8
array([[ True,  True,  True,  True,  True],
       [ True,  True,  True, False, False],
       [False, False, False, False, False]], dtype=bool)
複製代碼

基本的函數操做

>>> a
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14]])
# 縱向求和(軸索引爲 0)
>>> a.sum(axis=0)
array([15, 18, 21, 24, 27])
# 橫向求和(軸索引爲 1)
>>> a.sum(axis=1)
array([10, 35, 60])
# 每行的最小值(軸索引爲 1)
>>> a.min(axis=1)
array([ 0,  5, 10])
複製代碼

取數據

# 取索引 0,0 處的元素,也就是第一行第一個
>>> a[0,0]
0
# 取索引 2,3 處的元素
>>> a[2,3]
13
複製代碼

固然也能夠切片操做

# 取索引爲 1 到 2 (不含)的行,也就是第 2 行
>>> a[1:2]
array([[5, 6, 7, 8, 9]])
# 取索引爲 1 到 3 (不含)的行,索引爲 2 到 5(不含)的列
>>> a[1:3,2:5]
array([[ 7,  8,  9],
       [12, 13, 14]]))
複製代碼

還有其餘的數組轉換、線性代數計算等函數,就不詳細展開了。Numpy 就是咱們進行數據處理的基本容器,有了 Numpy 提供的數組結構,後面的操做就遊刃有餘了。

Scipy

Scipy 是數學、工程、科學計算相關的函數庫,自己是基於 Numpy 的數組的,也是和 Numpy 師出同門。

Scipy 有許多子模塊,每一個子模塊提供各個領域特定的功能。

  • cluster:聚類算法
  • constants:物理和數學的常量
  • fftpack:快速傅立葉變換
  • integrate:微積分方程求解
  • interpolate:插值計算
  • io:輸入輸出
  • linalg:線性代數
  • ndimage:n 維圖像處理
  • ord:正交距離迴歸
  • optimize:優化
  • signal:信號處理
  • sparse:稀疏矩陣
  • spatial:空間數據結構和算法
  • special:特殊函數
  • stats:統計分佈函數

各個函數的使用須要必定的理論基礎,scipy 已經幫助咱們實現,只須要調用便可。

例如,咱們計算以下的積分方程

>>> import scipy.integrate as integrate
>>> import scipy.special as special
>>> result = integrate.quad(lambda x: special.jv(2.5,x), 0, 4.5)
>>> result
(1.1178179380783249, 7.8663172481899801e-09)
複製代碼

是否是不再怕高數做業了?

Pandas

Pandas 不是一隻普通的熊貓。Pandas 是基於 Numpy 的高級的數據處理工具庫。Pandas 最擅長的就是處理表格數據,也就是咱們熟悉的 Excel 類型的數據,Pandas 提供的方法能讓咱們簡單的幾行代碼快速處理類 Excel 或者關係型數據表的數據。

一個最簡單的例子。

>>> import pandas as pd  # 和 nunpy 同樣的約定,通常引入後別名爲 pd
>>> df = pd.read_csv('test.csv')  # 讀取 csv 文件
>>> df  # 顯示讀取的內容,爲兩列三行的數據
     name  price
0   apple      5
1  banana      3
2    pear      2
>>> df.describe()  # 查看數據統計,自動找出數據列(price),計算相關統計量
          price
count  3.000000
mean   3.333333
std    1.527525
min    2.000000
25%    2.500000
50%    3.000000
75%    4.000000
max    5.000000
>>> df.price = df.price * 2  # 全部價格都乘以 2
>>> df
     name  price
0   apple     10
1  banana      6
2    pear      4
>>> df.to_csv('out.csv', index=False)  # 導出數據到 csv 文件
複製代碼

Pandas 能夠用來作數據清洗、轉換、聚合等操做,爲下一步數據可視化及機器學習準備數據。

Pandas 有多種數據類型,其中就常見的兩種就是 Series 和 DataFrame。

DataFrame 能夠理解爲一個數據表格,行有行的標籤(索引),列有列的標籤(索引),是否是和 Excel 很像?

而 Series 便是這個數據表格的一列或者一行。因此一個 DataFrame 也可看做是一個 Series 數組。

Pandas 提供了一系列的方法快速的從其餘數據源導入導出數據。

Pandas 也能很是方便的「挑選」特定的數據。

經過 Matplotlib 庫,Pandas 能夠方便的繪製可視化圖表。

對於基本的數據抽取、轉換、清洗等工做,Pandas 徹底能勝任,掌握了 Pandas 就有了應對各類敵人的百變戰甲。

Scikit-Learn

Scikit-Learn 是 Python 的機器學習庫,也是在 Numpy 和 Scipy 的基礎上,提供了強大的機器學習算法的實現。例如分類算法(SVM,K 近鄰,隨機森林等),迴歸算法(線性迴歸、SVR 等),聚類算法(K-means、譜聚類等)、降維、模型選擇、數據預處理等等。

Scikit-Learn 經過對算法的高度抽象,對於一個基本的算法調用過程,基本上就簡化爲了:初始化->數據預處理->訓練->預測,流程中的幾個步驟。

一個簡單的線性迴歸的例子。

>>> from sklearn import linear_model
>>> reg = linear_model.LinearRegression()
>>> reg.fit([[0, 0], [1, 1], [2, 2]], [0, 1, 2])
LinearRegression()
>>> reg.coef_
array([0.5, 0.5])
複製代碼

除了基本的算法實現,scikit-learn 提供的數據預處理也極其強大,基本能涵蓋數據預處理的許多方面。

例如,數據歸一化,快速的 Z-score 歸一化,使數據知足正態分佈。

>>> from sklearn import preprocessing
>>> import numpy as np
>>> X_train = np.array([[ 1., -1.,  2.],
...                     [ 2.,  0.,  0.],
...                     [ 0.,  1., -1.]])
>>> X_scaled = preprocessing.scale(X_train)

>>> X_scaled
array([[ 0.  ..., -1.22...,  1.33...],
       [ 1.22...,  0.  ..., -0.26...],
       [-1.22...,  1.22..., -1.06...]])
複製代碼

數據編碼,能夠將枚舉的字符串數據編碼爲數值型,方便後續計算。

>>> X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
>>> enc.fit(X)
OrdinalEncoder()
>>> enc.transform([['female', 'from US', 'uses Safari']])
array([[0., 1., 1.]])
複製代碼

One Hot 編碼,將枚舉字符串數據轉換爲多列的布爾數據(0 / 1)。

>>> X = [['male', 'from US', 'uses Safari'], ['female', 'from Europe', 'uses Firefox']]
>>> enc.fit(X)
OneHotEncoder()
>>> enc.transform([['female', 'from US', 'uses Safari'],
...                ['male', 'from Europe', 'uses Safari']]).toarray()
array([[1., 0., 0., 1., 0., 1.],
       [0., 1., 1., 0., 0., 1.]])
複製代碼

缺失值處理。

>>> import numpy as np
>>> from sklearn.impute import SimpleImputer
>>> imp = SimpleImputer(missing_values=np.nan, strategy='mean')
>>> imp.fit([[1, 2], [np.nan, 3], [7, 6]])
SimpleImputer()
>>> X = [[np.nan, 2], [6, np.nan], [7, 6]]
>>> print(imp.transform(X))
[[4.          2.        ]
 [6.          3.666...]
 [7.          6.        ]]
複製代碼

若是想要看一個實戰的項目,這裏有一個基因型預測身高的項目例子。該項目根據用戶在多個基因位點的基因型和身高數據進行模型訓練,而後可根據訓練的模型預測其餘用戶的身高。咱們先無論這個預測的理論可行性和準確性,不過整個數據預處理和模型訓練的操做是一個學習 scikit-learn 的過程。

Statsmodels

statsmodels 是一個 Python 的統計模型庫,提供了不少統計相關的函數和操做,例如線性迴歸、統計檢驗、時間序列分析等。statsmodels 也是構建在 Numpy、SciPy 和 Pandas 之上的。

線性迴歸模型

import statsmodels.api as sm

data = sm.datasets.scotland.load(as_pandas=False)  # 載入測試數據
data.exog = sm.add_constant(data.exog)

# 實例化伽馬模型
>>> gamma_model = sm.GLM(data.endog, data.exog, family=sm.families.Gamma())
>>> gamma_results = gamma_model.fit()
>>> print(gamma_results.summary())
                 Generalized Linear Model Regression Results                  
==============================================================================
Dep. Variable:                      y   No. Observations:                   32
Model:                            GLM   Df Residuals:                       24
Model Family:                   Gamma   Df Model:                            7
Link Function:          inverse_power   Scale:                       0.0035843
Method:                          IRLS   Log-Likelihood:                -83.017
Date:                Fri, 21 Feb 2020   Deviance:                     0.087389
Time:                        13:59:13   Pearson chi2:                   0.0860
No. Iterations:                     6                                         
Covariance Type:            nonrobust                                         
==============================================================================
                 coef    std err          z      P>|z|      [0.025      0.975]
------------------------------------------------------------------------------
const         -0.0178      0.011     -1.548      0.122      -0.040       0.005
x1          4.962e-05   1.62e-05      3.060      0.002    1.78e-05    8.14e-05
x2             0.0020      0.001      3.824      0.000       0.001       0.003
x3         -7.181e-05   2.71e-05     -2.648      0.008      -0.000   -1.87e-05
x4             0.0001   4.06e-05      2.757      0.006    3.23e-05       0.000
x5         -1.468e-07   1.24e-07     -1.187      0.235   -3.89e-07    9.56e-08
x6            -0.0005      0.000     -2.159      0.031      -0.001   -4.78e-05
x7         -2.427e-06   7.46e-07     -3.253      0.001   -3.89e-06   -9.65e-07
==============================================================================
複製代碼

方差分析

>>> import statsmodels.api as sm
>>> from statsmodels.formula.api import ols

>>> moore = sm.datasets.get_rdataset("Moore", "carData", cache=True) # 載入測試數據
>>> data = moore.data
>>> data = data.rename(columns={"partner.status": "partner_status"}) # 重命名
>>> moore_lm = ols('conformity ~ C(fcategory, Sum)*C(partner_status, Sum)', data=data).fit()
>>> table = sm.stats.anova_lm(moore_lm, typ=2) # Type 2 ANOVA DataFrame
>>> print(table)
                                              sum_sq    df          F    PR(>F)
C(fcategory, Sum)                          11.614700   2.0   0.276958  0.759564
C(partner_status, Sum)                    212.213778   1.0  10.120692  0.002874
C(fcategory, Sum):C(partner_status, Sum)  175.488928   2.0   4.184623  0.022572
Residual                                  817.763961  39.0        NaN       NaN
複製代碼

XGBoost

XGBoost 是一個改進的梯度加強算法(gradient boosting),基本的梯度加強算法(GBDT)已經在 scikit-learn 中有了實現。而 XGBoost 改進了該算法,提供了分佈式的能力,更快速,更靈活,更便攜。因爲 XGBoost 的簡單易學,性能高效和表現優異,經常被用於各類數據科學算法大賽。例如,著名的 Kaggle 大賽,XGBoost 是許多競賽的奪冠熱門算法。

XGBoost 是一個算法的名稱,可是提供衆多語言的實現,例如 Python, R, Java, Scala, C++ 等,同時也支持 Hadoop,Spark 等大數據生態。

若是須要詳細瞭解 GBDT 和 XGBoost 的前世此生,能夠戳這篇文章

這裏還有幾個 Kaggle 競賽項目的具體例子,能夠供你們直接學習。

後記

固然,數據處理的方式和算法實在是太多了,各類優化的算法庫也是層出不窮,還有很多 BI 軟件和商業化的工具。這裏展現的幾個算是這個領域中最大名鼎鼎的幾件大殺器,大殺器在手,蝦兵蟹將繞着走!

百媚生 Python《神兵譜》之數據分析-中篇,若是以爲有用,請點贊關注收藏哦!

參考

相關文章
相關標籤/搜索