Python數據分析之numpy學習(二)

我們接著《Python數據分析之numpy學習(一)》繼續講解有關numpy方面的知識!

統計函數與線性代數運算

統計運算中常見的聚合函數有:最小值、最大值、中位數、均值、方差、標準差等。首先來看看數組元素級別的計算:

In [94]: arr11 = 5-np.arange(1,13).reshape(4,3)

In [95]: arr12 = np.random.randint(1,10,size = 12).reshape(4,3)

In [96]: arr11

Out[96]:

array([[ 4, 3, 2],

[ 1, 0, -1],

[-2, -3, -4],

[-5, -6, -7]])

In [97]: arr12

Out[97]:

array([[1, 3, 7],

[7, 3, 7],

[3, 7, 4],

[6, 1, 2]])

In [98]: arr11 ** 2 #計算每個元素的平方

Out[98]:

array([[16, 9, 4],

[ 1, 0, 1],

[ 4, 9, 16],

[25, 36, 49]])

In [99]: np.sqrt(arr11) #計算每個元素的平方根

Out[99]:

array([[ 2. , 1.73205081, 1.41421356],

[ 1. , 0. , nan],

[ nan, nan, nan],

[ nan, nan, nan]])

由於負值的平方根沒有意義,故返回nan。

In [100]: np.exp(arr11) #計算每個元素的指數值

Out[100]:

array([[ 5.45981500e+01, 2.00855369e+01, 7.38905610e+00],

[ 2.71828183e+00, 1.00000000e+00, 3.67879441e-01],

[ 1.35335283e-01, 4.97870684e-02, 1.83156389e-02],

[ 6.73794700e-03, 2.47875218e-03, 9.11881966e-04]])

In [101]: np.log(arr12) #計算每個元素的自然對數值

Out[101]:

array([[ 0. , 1.09861229, 1.94591015],

[ 1.94591015, 1.09861229, 1.94591015],

[ 1.09861229, 1.94591015, 1.38629436],

[ 1.79175947, 0. , 0.69314718]])

In [102]: np.abs(arr11) #計算每個元素的絕對值

Out[102]:

array([[4, 3, 2],

[1, 0, 1],

[2, 3, 4],

[5, 6, 7]])

相同形狀數組間元素的操作:

In [103]: arr11 + arr12 #加

Out[103]:

array([[ 5, 6, 9],

[ 8, 3, 6],

[ 1, 4, 0],

[ 1, -5, -5]])

In [104]: arr11 - arr12 #減

Out[104]:

array([[ 3, 0, -5],

[ -6, -3, -8],

[ -5, -10, -8],

[-11, -7, -9]])

In [105]: arr11 * arr12 #乘

Out[105]:

array([[ 4, 9, 14],

[ 7, 0, -7],

[ -6, -21, -16],

[-30, -6, -14]])

In [106]: arr11 / arr12 #除

Out[106]:

array([[ 4. , 1. , 0.28571429],

[ 0.14285714, 0. , -0.14285714],

[-0.66666667, -0.42857143, -1. ],

[-0.83333333, -6. , -3.5 ]])

In [107]: arr11 // arr12 #整除

Out[107]:

array([[ 4, 1, 0],

[ 0, 0, -1],

[-1, -1, -1],

[-1, -6, -4]], dtype=int32)

In [108]: arr11 % arr12 #取余

Out[108]:

array([[0, 0, 2],

[1, 0, 6],

[1, 4, 0],

[1, 0, 1]], dtype=int32)

接下來我們看看統計運算函數:

In [109]: np.sum(arr11) #計算所有元素的和

Out[109]: -18

In [110]: np.sum(arr11,axis = 0) #對每一列求和

Out[110]: array([ -2, -6, -10])

In [111]: np.sum(arr11, axis = 1) #對每一行求和

Out[111]: array([ 9, 0, -9, -18])

In [112]: np.cumsum(arr11) #對每一個元素求累積和(從上到下,從左到右的元素順序)

Out[112]: array([ 4, 7, 9, 10, 10, 9, 7, 4, 0, -5, -11, -18], dtype=int32)

In [113]: np.cumsum(arr11, axis = 0) #計算每一列的累積和,並返回二維數組

Out[113]:

array([[ 4, 3, 2],

[ 5, 3, 1],

[ 3, 0, -3],

[ -2, -6, -10]], dtype=int32)

In [114]: np.cumprod(arr11, axis = 1) #計算每一行的累計積,並返回二維數組

Out[114]:

array([[ 4, 12, 24],

[ 1, 0, 0],

[ -2, 6, -24],

[ -5, 30, -210]], dtype=int32)

In [115]: np.min(arr11) #計算所有元素的最小值

Out[115]: -7

In [116]: np.max(arr11, axis = 0) #計算每一列的最大值

Out[116]: array([4, 3, 2])

In [117]: np.mean(arr11) #計算所有元素的均值

Out[117]: -1.5

In [118]: np.mean(arr11, axis = 1) #計算每一行的均值

Out[118]: array([ 3., 0., -3., -6.])

In [119]: np.median(arr11) #計算所有元素的中位數

Out[119]: -1.5

In [120]: np.median(arr11, axis = 0) #計算每一列的中位數

Out[120]: array([-0.5, -1.5, -2.5])

In [121]: np.var(arr12) #計算所有元素的方差

Out[121]: 5.354166666666667

In [122]: np.std(arr12, axis = 1) #計算每一行的標準差

Out[122]: array([ 2.49443826, 1.88561808, 1.69967317, 2.1602469 ])

numpy中的統計函數運算是非常靈活的,既可以計算所有元素的統計值,也可以計算指定行或列的統計指標。還有其他常用的函數,如符號函數sign,ceil(>=x的最小整數),floor(<>

讓我很興奮的一個函數是where(),它類似於Excel中的if函數,可以進行靈活的變換:

In [123]: arr11

Out[123]:

array([[ 4, 3, 2],

[ 1, 0, -1],

[-2, -3, -4],

[-5, -6, -7]])

In [124]: np.where(arr11 < 0,="">

Out[124]:

array([["positive", "positive", "positive"],

["positive", "positive", "negtive"],

["negtive", "negtive", "negtive"],

["negtive", "negtive", "negtive"]],

dtype="<>< span=""><>

當然,np.where還可以嵌套使用,完成複雜的運算。

其它函數

unique(x):計算x的唯一元素,並返回有序結果

intersect(x,y):計算x和y的公共元素,即交集

union1d(x,y):計算x和y的並集

setdiff1d(x,y):計算x和y的差集,即元素在x中,不在y中

setxor1d(x,y):計算集合的對稱差,即存在於一個數組中,但不同時存在於兩個數組中

in1d(x,y):判斷x的元素是否包含於y中

線性代數運算

同樣numpu也跟R語言一樣,可以非常方便的進行線性代數方面的計算,如行列式、逆、跡、特徵根、特徵向量等。但需要注意的是,有關線性代數的函數並不在numpy中,而是numpy的子例linalg中。

In [125]: arr13 = np.array([[1,2,3,5],[2,4,1,6],[1,1,4,3],[2,5,4,1]])

In [126]: arr13

Out[126]:

array([[1, 2, 3, 5],

[2, 4, 1, 6],

[1, 1, 4, 3],

[2, 5, 4, 1]])

In [127]: np.linalg.det(arr13) #返回方陣的行列式

Out[127]: 51.000000000000021

In [128]: np.linalg.inv(arr13) #返回方陣的逆

Out[128]:

array([[-2.23529412, 1.05882353, 1.70588235, -0.29411765],

[ 0.68627451, -0.25490196, -0.7254902 , 0.2745098 ],

[ 0.19607843, -0.21568627, 0.07843137, 0.07843137],

[ 0.25490196, 0.01960784, -0.09803922, -0.09803922]])

In [129]: np.trace(arr13) #返回方陣的跡(對角線元素之和),注意跡的求解不在linalg子常式中

Out[129]: 10

In [130]: np.linalg.eig(arr13) #返回由特徵根和特徵向量組成的元組

Out[130]:

(array([ 11.35035004, -3.99231852, -0.3732631 , 3.01523159]),

array([[-0.4754174 , -0.48095078, -0.95004728, 0.19967185],

[-0.60676806, -0.42159999, 0.28426325, -0.67482638],

[-0.36135292, -0.16859677, 0.08708826, 0.70663129],

[-0.52462832, 0.75000995, 0.09497472, -0.07357122]]))

In [131]: np.linalg.qr(arr13) #返回方陣的QR分解

Out[131]:

(array([[-0.31622777, -0.07254763, -0.35574573, -0.87645982],

[-0.63245553, -0.14509525, 0.75789308, -0.06741999],

[-0.31622777, -0.79802388, -0.38668014, 0.33709993],

[-0.63245553, 0.580381 , -0.38668014, 0.33709993]]),

array([[-3.16227766, -6.64078309, -5.37587202, -6.95701085],

[ 0. , 1.37840488, -1.23330963, -3.04700025],

[ 0. , 0. , -3.40278524, 1.22190924],

[ 0. , 0. , 0. , -3.4384193 ]]))

In [132]:np.linalg.svd(arr13) #返回方陣的奇異值分解

Out[132]:

(array([[-0.50908395, 0.27580803, 0.35260559, -0.73514132],

[-0.59475561, 0.4936665 , -0.53555663, 0.34020325],

[-0.39377551, -0.10084917, 0.70979004, 0.57529852],

[-0.48170545, -0.81856751, -0.29162732, -0.11340459]]),

array([ 11.82715609, 4.35052602, 3.17710166, 0.31197297]),

array([[-0.25836994, -0.52417446, -0.47551003, -0.65755329],

[-0.10914615, -0.38326507, -0.54167613, 0.74012294],

[-0.18632462, -0.68784764, 0.69085326, 0.12194478],

[ 0.94160248, -0.32436807, -0.05655931, -0.07050652]]))

In [133]: np.dot(arr13,arr13) #方陣的正真乘積運算

Out[133]:

array([[18, 38, 37, 31],

[23, 51, 38, 43],

[13, 25, 32, 26],

[18, 33, 31, 53]])

In [134]:arr14 = np.array([[1,-2,1],[0,2,-8],[-4,5,9]])

In [135]: vector = np.array([0,8,-9])

In [136]: np.linalg.solve(arr14,vector)

Out[136]: array([ 29., 16., 3.])

隨機數生成

統計學中經常會講到數據的分布特徵,如正態分布、指數分布、卡方分布、二項分布、泊松分布等,下面就講講有關分布的隨機數生成。

正態分布直方圖

In [137]: import matplotlib #用於繪圖的模塊

In [138]: np.random.seed(1234) #設置隨機種子

In [139]: N = 10000 #隨機產生的樣本量

In [140]: randnorm = np.random.normal(size = N) #生成正態隨機數

In [141]: counts, bins, path = matplotlib.pylab.hist(randnorm, bins = np.sqrt(N), normed = True, color = "blue") #繪製直方圖

以上將直方圖的頻數和組距存放在counts和bins內。

In [142]: sigma = 1; mu = 0

In [143]: norm_dist = (1/np.sqrt(2*sigma*np.pi))*np.exp(-((bins-mu)**2)/2) #正態分布密度函數

In [144]: matplotlib.pylab.plot(bins,norm_dist,color = "red") #繪製正態分布密度函數圖

使用二項分布進行賭博

同時拋棄9枚硬幣,如果正面朝上少於5枚,則輸掉8元,否則就贏8元。如果手中有1000元作為賭資,請問賭博10000次後可能會是什麼情況呢?

In [146]: np.random.seed(1234)

In [147]: binomial = np.random.binomial(9,0.5,10000) #生成二項分布隨機數

In [148]: money = np.zeros(10000) #生成10000次賭資的列表

In [149]: money[0] = 1000 #首次賭資為1000元

In [150]: for i in range(1,10000):

...: if binomial[i] <>

...: money[i] = money[i-1] - 8

#如果少於5枚正面,則在上一次賭資的基礎上輸掉8元

...: else:

...: money[i] = money[i-1] + 8

#如果至少5枚正面,則在上一次賭資的基礎上贏取8元

In [151]: matplotlib.pylab.plot(np.arange(10000), money)

使用隨機整數實現隨機遊走

一個醉漢在原始位置上行走10000步後將會在什麼地方呢?如果他每走一步是隨機的,即下一步可能是1也可能是-1。

In [152]: np.random.seed(1234) #設定隨機種子

In [153]: position = 0 #設置初始位置

In [154]: walk = [] #創建空列表

In [155]: steps = 10000 #假設接下來行走10000步

In [156]: for i in np.arange(steps):

...: step = 1 if np.random.randint(0,2) else -1 #每一步都是隨機的

...: position = position + step #對每一步進行累計求和

...: walk.append(position) #確定每一步所在的位置

In [157]: matplotlib.pylab.plot(np.arange(10000), walk) #繪製隨機遊走圖

上面的代碼還可以寫成(結合前面所講的where函數,cumsum函數):

In [158]: np.random.seed(1234)

In [159]: step = np.where(np.random.randint(0,2,10000)>0,1,-1)

In [160]: position = np.cumsum(step)

In [161]: matplotlib.pylab.plot(np.arange(10000), position)

避免for循環,可以達到同樣的效果。

使用Python進行數據分析,一般都會使用到numpy,pandas,scipy和matplotlib等模塊,而numpy是最為基礎的模塊,其他模塊的使用都是以numpy為核心,所以這裡講解了有關numpy的方方面面,這部分的學習非常重要,希望感興趣的朋友多看看這方面的文檔和動手操作。在接下來Python一期中將會講到pandas模塊的學習。


推薦閱讀:

肝風內動證,四證分析詳解
弘恩法師:婚外情是真愛嗎?這些分析給你答案
【一點資訊】從八字分析看哪些男人容易娶到富家女?
進行基督教教育的各種異議分析
女命八字實例分析——七殺貼身相剋

TAG:學習 | Python | 數據分析 | 數據 | numpy | 分析 |