小白的Python學習筆記(十六)數據挖掘經常使用包 - Numpy

NumPy是什麼?

今天開始會陸續爲你們帶來數據科學經常使用包的基礎用法python

數據分析的工做涉及到大量的數值運算,一個高效方便的科學計算工具是必不可少的。Python語言一開始並非設計爲科學計算使用的語言,隨着愈來愈多的人發現Python的易用性,逐漸出現了關於Python的大量外部擴展,Numpy (Numeric Python)就是其中之一。編程

Numpy提供了大量的數值編程工具,能夠方便地處理向量、矩陣等運算,極大地便利了人們在科學計算方面的工做。另外一方面,Python是免費,相比於花費高額的費用使用Matlab,Numpy的出現使Python獲得了更多人的青睞。數組

咱們能夠簡單看一下如何開始使用NumPy:dom

import numpy as np
numpy.version.full_version
複製代碼
'1.16.4'
複製代碼

2、NumPy對象:數組

NumPy中的基本對象是同類型的多維數組(homogeneous multidimensional array),這和C++中的數組是一致的,例如字符型和數值型就不可共存於同一個數組中。先上例子:函數

a = np.arange(20)
print(a)
複製代碼
[ 0  1  2  3  4  5  6  7  8  9 10 11 12 13 14 15 16 17 18 19]
複製代碼

這裏咱們生成了一個一維數組a,從0開始,步長爲1,長度爲20。Python中的計數是從0開始的,R和Matlab的使用者須要當心。工具

咱們能夠經過"type"函數查看a的類型,這裏顯示a是一個array:spa

type(a)
複製代碼
numpy.ndarray
複製代碼

經過函數"reshape",咱們能夠從新構造一下這個數組,例如,咱們能夠構造一個4*5的二維數組,其中"reshape"的參數表示各維度的大小,且按各維順序排列(兩維時就是按行排列,這和R中按列是不一樣的):設計

a = a.reshape(4, 5)
print(a)
複製代碼
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
複製代碼

構造更高維的也沒問題:code

a = a.reshape(2, 2, 5)
print(a)
複製代碼
[[[ 0  1  2  3  4]
  [ 5  6  7  8  9]]

 [[10 11 12 13 14]
  [15 16 17 18 19]]]
複製代碼

既然a是array,咱們還能夠調用array的函數進一步查看a的相關屬性:"ndim"查看維度;"shape"查看各維度的大小;"size"查看所有的元素個數,等於各維度大小的乘積;"dtype"可查看元素類型;"dsize"查看元素佔位(bytes)大小。對象

a.ndim
複製代碼
3
複製代碼
a.shape
複製代碼
(2, 2, 5)
複製代碼
a.size
複製代碼
20
複製代碼
a.dtype
複製代碼
dtype('int32')
複製代碼

3、建立數組

數組的建立可經過轉換列表實現,高維數組可經過轉換嵌套列表實現:

raw = [0,1,2,3,4]
a = np.array(raw)
a
複製代碼
array([0, 1, 2, 3, 4])
複製代碼
raw = [[0,1,2,3,4], [5,6,7,8,9]]
b = np.array(raw)
b
複製代碼
array([[0, 1, 2, 3, 4],
       [5, 6, 7, 8, 9]])
複製代碼

一些特殊的數組有特別定製的命令生成,如4*5的全零矩陣:

d = (4, 5)
np.zeros(d)
複製代碼
array([[0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.],
       [0., 0., 0., 0., 0.]])
複製代碼

默認生成的類型是浮點型,能夠經過指定類型改成整型:

d = (4, 5)
np.ones(d, dtype=int)
複製代碼
array([[1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1],
       [1, 1, 1, 1, 1]])
複製代碼

[0, 1)區間的隨機數數組:

np.random.rand(5)
複製代碼
array([0.80378557, 0.09833667, 0.95280995, 0.17707594, 0.80651926])
複製代碼

服從正態分佈的隨機數組:

np.random.randn(5)
複製代碼
array([ 0.678737  , -1.14965615, -1.40492579,  1.22479651,  0.2751816 ])
複製代碼

4、數組操做

簡單的四則運算已經重載過了,所有的'+','-','*','/'運算都是基於所有的數組元素的,以加法爲例:

a = np.array([[1.0, 2], [2, 4]])
print ("a:\n",a)

b = np.array([[3.2, 1.5], [2.5, 4]])
print ("b:\n",b)
print ("a+b:\n",a+b)
複製代碼
a:
 [[1. 2.]
 [2. 4.]]
b:
 [[3.2 1.5]
 [2.5 4. ]]
a+b:
 [[4.2 3.5]
 [4.5 8. ]]
複製代碼

這裏能夠發現,a中雖然僅有一個與元素是浮點數,其他均爲整數,在處理中Python會自動將整數轉換爲浮點數(由於數組是同質的),而且,兩個二維數組相加要求各維度大小相同。固然,NumPy裏這些運算符也能夠對標量和數組操做,結果是數組的所有元素對應這個標量進行運算,仍是一個數組:

print ("3 * a \n",3*a)
print ("b + 1.8 \n",b )
複製代碼
3 * a :
 [[ 3.  6.]
 [ 6. 12.]]
b + 1.8 
 [[3.2 1.5]
 [2.5 4. ]]
複製代碼

相似C++,'+='、'-='、'*='、'/='操做符在NumPy中一樣支持:

a /= 2
a
複製代碼
array([[0.5, 1. ],
       [1. , 2. ]])
複製代碼

開根號求指數也很容易:

print(a)
複製代碼
[[0.5 1. ]
 [1.  2. ]]
複製代碼
print ("np.exp:\n",np.exp(a))
複製代碼
np.exp:
 [[1.64872127 2.71828183]
 [2.71828183 7.3890561 ]]
複製代碼
print ("np.sqrt:\n",np.sqrt(a))
複製代碼
np.sqrt:
 [[0.70710678 1.        ]
 [1.         1.41421356]]
複製代碼
print ("np.square:\n",np.square(a))
複製代碼
np.square:
 [[0.25 1.  ]
 [1.   4.  ]]
複製代碼
print ("np.power:\n",np.power(a,3))
複製代碼
np.power:
 [[0.125 1.   ]
 [1.    8.   ]]
複製代碼

須要知道二維數組的最大最小值怎麼辦?想計算所有元素的和、按行求和、按列求和怎麼辦?NumPy的ndarray類已經作好函數了:

a = np.arange(20).reshape(4,5)
a
複製代碼
array([[ 0,  1,  2,  3,  4],
       [ 5,  6,  7,  8,  9],
       [10, 11, 12, 13, 14],
       [15, 16, 17, 18, 19]])
複製代碼
print("sum of all elements in a: " + str(a.sum()))
print("maximum element in a: " + str(a.max()))
print("minimum element in a: " + str(a.min()))
print("maximum element in each row of a: " + str(a.max(axis=1)))
print("minimum element in each column of a: " + str(a.min(axis=0)))
複製代碼
sum of all elements in a: 190
maximum element in a: 19
minimum element in a: 0
maximum element in each row of a: [ 4  9 14 19]
minimum element in each column of a: [0 1 2 3 4]
複製代碼

科學計算中大量使用到矩陣運算,除了數組,NumPy同時提供了矩陣對象(matrix)。矩陣對象和數組的主要有兩點差異:一是矩陣是二維的,而數組的能夠是任意正整數維;二是矩陣的'*'操做符進行的是矩陣乘法,乘號左側的矩陣列和乘號右側的矩陣行要相等,而在數組中'*'操做符進行的是每一元素的對應相乘,乘號兩側的數組每一維大小須要一致。數組能夠經過asmatrix或者mat轉換爲矩陣,或者直接生成也能夠:

a = np.arange(20).reshape(4, 5)
a = np.asmatrix(a)
print(type(a))

b = np.matrix('1.0 2.0; 3.0 4.0')
print(type(b))
複製代碼
<class 'numpy.matrix'>
<class 'numpy.matrix'>
複製代碼

再來看一下矩陣的乘法,這使用arange生成另外一個矩陣b,arange函數還能夠經過arange(起始,終止,步長)的方式調用生成等差數列,注意含頭不含尾。

b = np.arange(2, 45, 3).reshape(5, 3)
b = np.mat(b)
print(b)
複製代碼
[[ 2  5  8]
 [11 14 17]
 [20 23 26]
 [29 32 35]
 [38 41 44]]
複製代碼

回到咱們的問題,矩陣a和b作矩陣乘法:

print ("matrix a:\n",a)
print("matrix b:\n",b)

c = a * b
print("matrix c:\n",c)
複製代碼
matrix a:
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
matrix b:
 [[ 2  5  8]
 [11 14 17]
 [20 23 26]
 [29 32 35]
 [38 41 44]]
matrix c:
 [[ 290  320  350]
 [ 790  895 1000]
 [1290 1470 1650]
 [1790 2045 2300]]
複製代碼

5、數組元素訪問

數組和矩陣元素的訪問可經過下標進行,如下均以二維數組(或矩陣)爲例:

a = np.array([[3.2, 1.5], [2.5, 4]])
print(a[0][1])
print(a[0, 1])
複製代碼
1.5
1.5
複製代碼

能夠經過下標訪問來修改數組元素的值:

b = a
a[0][1] = 2.0
print(a)
print(b)
複製代碼
[[3.2 2. ]
 [2.5 4. ]]
[[3.2 2. ]
 [2.5 4. ]]
複製代碼

如今問題來了,明明改的是a[0][1],怎麼連b[0][1]也跟着變了?這個陷阱在Python編程中很容易碰上,其緣由在於Python不是真正將a複製一份給b,而是將b指到了a對應數據的內存地址上。想要真正的複製一份a給b,可使用copy:

a = np.array([[3.2, 1.5], [2.5, 4]])
b = a.copy()
a[0][1] = 2.0
print ("a:",a)
print ("b:",b)

複製代碼
a: [[3.2 2. ]
 [2.5 4. ]]
b: [[3.2 1.5]
 [2.5 4. ]]
複製代碼

若對a從新賦值,即將a指到其餘地址上,b仍在原來的地址上:

a = np.array([[3.2, 1.5], [2.5, 4]])
b = a
a = np.array([[2, 1], [9, 3]])
print ("a:\n",a)
print ("b:\n",b)
複製代碼
a:
 [[2 1]
 [9 3]]
b:
 [[3.2 1.5]
 [2.5 4. ]]
複製代碼

利用':'能夠訪問到某一維的所有數據,例如取矩陣中的指定列:

a = np.arange(20).reshape(4, 5)
print ("a:\n",a)
print ("the 2nd and 4th column of a::\n",a[:,[1,3]])
複製代碼
a:
 [[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]
 [15 16 17 18 19]]
the 2nd and 4th column of a::
 [[ 1  3]
 [ 6  8]
 [11 13]
 [16 18]]
複製代碼

稍微複雜一些,咱們嘗試取出知足某些條件的元素,這在數據的處理中十分常見,一般用在單行單列上。下面這個例子是將第一列大於5的元素(10和15)對應的第三列元素(12和17)取出來:

a[:, 2][a[:, 0] > 5]
複製代碼
array([12, 17])
複製代碼

可以使用where函數查找特定值在數組中的位置:

loc = numpy.where(a==11)
print(loc)
print(a[loc[0][0], loc[1][0]])
複製代碼
(array([2], dtype=int64), array([1], dtype=int64))
11
複製代碼

6、數組操做

仍是拿矩陣(或二維數組)做爲例子,首先來看矩陣轉置:

a = np.random.rand(2,4)
print ("a:\n",a)
a = np.transpose(a)
print ("a is an array, by using transpose(a):\n",a)

b = np.random.rand(2,4)
b = np.mat(b)
print ("b:\n",b)
print ("b is a matrix, by using b.T:\n",b.T)
複製代碼
a:
 [[0.49632956 0.65061015 0.36037379 0.29664563]
 [0.18319505 0.45525932 0.08422801 0.75167911]]
a is an array, by using transpose(a):
 [[0.49632956 0.18319505]
 [0.65061015 0.45525932]
 [0.36037379 0.08422801]
 [0.29664563 0.75167911]]
b:
 [[0.51087064 0.2058778  0.88659661 0.78428426]
 [0.62716285 0.46838085 0.63015861 0.69754748]]
b is a matrix, by using b.T:
 [[0.51087064 0.62716285]
 [0.2058778  0.46838085]
 [0.88659661 0.63015861]
 [0.78428426 0.69754748]]
複製代碼

矩陣求逆:

import numpy.linalg as nlg
a = np.random.rand(2,2)
print ("a:\n",a)
ia = nlg.inv(a)
print ("inverse of a:\n",ia)
print ("a * inv(a):\n",a * ia)
複製代碼
a:
 [[0.7748124  0.08125528]
 [0.99696367 0.73251292]]
inverse of a:
 [[ 1.50551971 -0.16700242]
 [-2.04904025  1.59245703]]
a * inv(a):
 [[ 1.16649535 -0.01356983]
 [-2.04281868  1.16649535]]
複製代碼

求特徵值和特徵向量

a = np.random.rand(3,3)
eig_value, eig_vector = nlg.eig(a)

print ("eigen value:\n",eig_value)
print ("eigen vector:\n",eig_vector)
複製代碼
eigen value:
 [ 1.75590394+0.j         -0.25188941+0.08867887j -0.25188941-0.08867887j]
eigen vector:
 [[ 0.33976986+0.j          0.47679494-0.21597791j  0.47679494+0.21597791j]
 [ 0.81509742+0.j          0.24255425+0.21077809j  0.24255425-0.21077809j]
 [ 0.46922557+0.j         -0.78915154+0.j         -0.78915154-0.j        ]]
複製代碼

按列拼接兩個向量成一個矩陣:

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

在循環處理某些數據獲得結果後,將結果拼接成一個矩陣是十分有用的,能夠經過vstack和hstack完成:

a = np.random.rand(2,2)
b = np.random.rand(2,2)
print ("a:\n",a)
print ("b:\n",b)
c = np.hstack([a,b])
d = np.vstack([a,b])
print("horizontal stacking a and b:\n",c)
print("vertical stacking a and b:\n",d)
複製代碼
a:
 [[0.50331973 0.49651025]
 [0.89325327 0.31245265]]
b:
 [[0.35846554 0.56841584]
 [0.88041789 0.81287829]]
horizontal stacking a and b:
 [[0.50331973 0.49651025 0.35846554 0.56841584]
 [0.89325327 0.31245265 0.88041789 0.81287829]]
vertical stacking a and b:
 [[0.50331973 0.49651025]
 [0.89325327 0.31245265]
 [0.35846554 0.56841584]
 [0.88041789 0.81287829]]
複製代碼

7、缺失值

缺失值在分析中也是信息的一種,NumPy提供nan做爲缺失值的記錄,經過isnan斷定。

a = np.random.rand(2,2)
a[0, 1] = np.nan
print(np.isnan(a))
複製代碼
[[False  True]
 [False False]]
複製代碼

nan_to_num可用來將nan替換成0,pandas中提供能指定nan替換值的函數。

print(np.nan_to_num(a))
複製代碼
[[0.04279427 0.        ]
 [0.08386045 0.3567586 ]]
複製代碼

參考文獻

  1. wiki.scipy.org/Tentative_N…
  2. Sheppard K. Introduction to Python for econometrics, statistics and data analysis. Self-published, University of Oxford, version, 2012, 2.
相關文章
相關標籤/搜索