1. 程式人生 > >AI學習之路(6): NumPy的使用

AI學習之路(6): NumPy的使用

前面學習怎麼樣檢視numpy的版本號,這才是剛剛開始,現在來開始更深入地學習一下它,否則以後會很麻煩的,更加看不懂那些例子的程式碼了。

一個用python實現的科學計算包。包括:

1、一個強大的N維陣列物件Array;

2、比較成熟的(廣播)函式庫;

3、用於整合C/C++和Fortran程式碼的工具包;

4、實用的線性代數、傅立葉變換和隨機數生成函式。

numpy和稀疏矩陣運算包scipy配合使用更加方便。NumPy(Numeric Python)提供了許多高階的數值程式設計工具,如:矩陣資料型別、向量處理,以及精密的運算庫。專為進行嚴格的數字處理而產生。多為很多大型金融公司使用,以及核心的科學計算組織如:Lawrence Livermore,NASA用其處理一些本來使用C++,Fortran或Matlab等所做的任務。

NumPy的主要物件是同種元素的多維陣列。這是一個所有的元素都是一種型別、通過一個正整數元組索引的元素表格(通常是元素是數字)。在NumPy中維度(dimensions)叫做軸(axes),軸的個數叫做秩(rank)。


例如,在3D空間一個點的座標 [1, 2, 3] 是一個秩為1的陣列,因為它只有一個軸。那個軸長度為3.又例如,在以下例子中,陣列的秩為2(它有兩個維度).第一個維度長度為2,第二個維度長度為3.


[[ 1., 0., 0.],
 [ 0., 1., 2.]]
NumPy的陣列類被稱作 ndarray 。通常被稱作陣列。注意numpy.array和標準Python庫類array.array並不相同,後者只處理一維陣列和提供少量功能。更多重要ndarray物件屬性有:


ndarray.ndim


陣列軸的個數,在python的世界中,軸的個數被稱作秩


ndarray.shape


陣列的維度。這是一個指示陣列在每個維度上大小的整數元組。例如一個n排m列的矩陣,它的shape屬性將是(2,3),這個元組的長度顯然是秩,即維度或者ndim屬性


ndarray.size


陣列元素的總個數,等於shape屬性中元組元素的乘積。


ndarray.dtype


一個用來描述陣列中元素型別的物件,可以通過創造或指定dtype使用標準Python型別。另外NumPy提供它自己的資料型別。


ndarray.itemsize


陣列中每個元素的位元組大小。例如,一個元素型別為float64的陣列itemsiz屬性值為8(=64/8),又如,一個元素型別為complex32的陣列item屬性為4(=32/8).


ndarray.data


包含實際陣列元素的緩衝區,通常我們不需要使用這個屬性,因為我們總是通過索引來使用陣列中的元素。

下面來學習一個小例子:

#python 3.5.3  蔡軍生  
#http://edu.csdn.net/course/detail/2592  
#  
import numpy as np
a = np.arange(15).reshape(3, 5)
print(a) #顯示陣列

print(a.shape) #多少行多少列
print(a.ndim) #維度
print(a.dtype.name) #元素型別名稱
print(a.itemsize) #每一項的大小
print(a.size) #陣列總個數
print(type(a)) #陣列型別

b = np.array([6, 7, 8])  #建立陣列
print(b)
print(type(b))

輸出結果如下:

====================== RESTART: D:/AI/sample/tf_1.4.py ======================
[[ 0  1  2  3  4]
 [ 5  6  7  8  9]
 [10 11 12 13 14]]
(3, 5)
2
int32
4
15
<class 'numpy.ndarray'>
[6 7 8]
<class 'numpy.ndarray'>
>>> 

用列表來建立陣列

#python 3.5.3  蔡軍生  
#http://edu.csdn.net/course/detail/2592  
#  
import numpy as np

#使用列表建立陣列
a = np.array( [2,3,4] )
print(a)

#使用列表的元組來建立二維陣列
b = np.array( [ (1.5,2,3), (4,5,6) ] )
print(b)

#使用列表的元組來建立三維陣列
c = np.array( [ (1.5,2,3), (4,5,6) , (7,8,9)] )
print(c)

結果輸出如下:

====================== RESTART: D:/AI/sample/tf_1.5.py ======================
[2 3 4]
[[ 1.5  2.   3. ]
 [ 4.   5.   6. ]]
[[ 1.5  2.   3. ]
 [ 4.   5.   6. ]
 [ 7.   8.   9. ]]
>>> 

在建立陣列時,也可以指定陣列元素的型別。同時,由於很多時候,並不知道值是什麼,這樣就需要建立一個空的陣列。比如下面的例子:

#python 3.5.3  蔡軍生  
#http://edu.csdn.net/course/detail/2592  
#  
import numpy as np

#使用建立陣列時指定型別
c = np.array( [ [1,2], [3,4] ], dtype=complex )
print(c)

#
d = np.zeros( (3, 4) )
print(d)

e = np.ones( (2,3,4), dtype=np.int16 )
print(e)

f = np.empty( (2,3) )
print(f)

結果輸出如下:

====================== RESTART: D:/AI/sample/tf_1.6.py ======================
[[ 1.+0.j  2.+0.j]
 [ 3.+0.j  4.+0.j]]
[[ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]
 [ 0.  0.  0.  0.]]
[[[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]


 [[1 1 1 1]
  [1 1 1 1]
  [1 1 1 1]]]
[[ 0.  0.  0.]
 [ 0.  0.  0.]]
>>>

為了建立一些序數陣列,那麼使用列表就不是那麼方便了,因而numpy提供建立的函式arange,它與range是相似的功能,使用如下:

#python 3.5.3  蔡軍生  
#http://edu.csdn.net/course/detail/2592  
#  
import numpy as np

#使用函式arange建立等距離的陣列
a = np.arange( 10, 30, 5 )
print(a)

a = np.arange( 10, 30, 1 )
print(a)

a = np.arange( 10, 30, 2.2 )
print(a)

結果輸出如下:

====================== RESTART: D:/AI/sample/tf_1.7.py ======================
[10 15 20 25]
[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29]
[ 10.   12.2  14.4  16.6  18.8  21.   23.2  25.4  27.6  29.8]
>>> 

可見函式arange是類似於python的range函式,通過指定開始值、終值和步長來建立一維陣列,注意陣列不包括終值。

如果想改變這些一維陣列,比如改為多維陣列,但引數的元素內容不改變:

#python 3.5.3  蔡軍生  
#http://edu.csdn.net/course/detail/2592  
#  
import numpy as np

#使用函式arange建立等距離的陣列
a = np.arange( 10, 30, 5 )
print(a)

a = np.arange( 10, 30, 1 )
print(a)

print(a.reshape(5,4))
輸出如下:

====================== RESTART: D:/AI/sample/tf_1.8.py ======================
[10 15 20 25]
[10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29]
[[10 11 12 13]
 [14 15 16 17]
 [18 19 20 21]
 [22 23 24 25]
 [26 27 28 29]]
>>> 

numpy.random.rand(d0, d1, ..., dn)
產生多維指定值的隨機值陣列。建立一個給定型別的陣列,將其填充在一個均勻分佈的隨機樣本[0, 1)中
引數:
d0, d1, ..., dn : int, 型別可選
返回陣列的大小,都應該是正的。如果沒有給定型別,將要返回float型別陣列。
返回值:
輸出: 陣列, 維數 (d0, d1, ..., dn)的隨機值

例子如下:

#python 3.5.3  蔡軍生  
#http://edu.csdn.net/course/detail/2592  
#  
import numpy as np

#生成隨機陣列
a = np.random.rand(100)
print(a)
結果輸出如下:

====================== RESTART: D:/AI/sample/tf_1.8.py ======================
[ 0.36756623  0.57475991  0.11576291  0.19575305  0.22775931  0.02877083
  0.87709383  0.82610854  0.95336226  0.33116793  0.41715486  0.41567563
  0.93325899  0.82980251  0.2641698   0.0230075   0.16021737  0.89062266
  0.53174089  0.88560318  0.1020577   0.51347666  0.20543881  0.68847073
  0.67691318  0.73267761  0.02955434  0.33115342  0.57108833  0.89842244
  0.29627328  0.44781693  0.27565271  0.9583813   0.69200277  0.86579612
  0.1317431   0.5361843   0.23088806  0.43096172  0.30871722  0.21351671
  0.35913488  0.64517815  0.14824364  0.02528712  0.02719144  0.87200391
  0.1873583   0.06465166  0.59395243  0.1620941   0.00949225  0.6715625
  0.01759062  0.48881549  0.48537134  0.73747324  0.76030959  0.00108733
  0.34658235  0.98244906  0.90418067  0.09229615  0.17773136  0.59418644
  0.10831246  0.09145009  0.27159286  0.86183618  0.97369326  0.38035745
  0.46369083  0.69789643  0.81394915  0.62409341  0.33483406  0.41672463
  0.18458513  0.06065934  0.57065936  0.63319788  0.35979201  0.35651482
  0.07786763  0.27354799  0.51581137  0.58519992  0.41066551  0.85583774
  0.85858194  0.65743586  0.69588964  0.3069319   0.33913916  0.27590068
  0.7522814   0.95541998  0.66847512  0.28899663]
>>> 

接著下來,我們玩玩numpy的數值資料型別轉換。很多時候我們用numpy從文字檔案讀取資料作為numpy的陣列,預設的dtype是float64。
但是有些場合我們希望有些資料列作為整數。如果直接改dtype=‘int‘的話,就會出錯!原因如上,陣列長度翻倍了!!!

#python 3.5.3  蔡軍生  
#http://edu.csdn.net/course/detail/2592  
#  
import numpy as np

#生成隨機陣列
a = np.random.rand(100)
print(a)
print(a.dtype)

#改變為float32
b = a.astype(np.float32)
print(b.dtype)
結果輸出如下:

====================== RESTART: D:/AI/sample/tf_1.9.py ======================
[ 0.77584611  0.52876856  0.19706401  0.61832623  0.0089896   0.41983348
  0.10492766  0.97979312  0.69085108  0.86499159  0.39013642  0.44552474
  0.8411643   0.56789924  0.65441475  0.11682472  0.16229718  0.71352883
  0.1733354   0.73853152  0.46474821  0.33760637  0.5414772   0.19916713
  0.14423215  0.76983785  0.19381022  0.01049321  0.67666048  0.92127875
  0.8633769   0.21072991  0.20734093  0.35363864  0.38049275  0.34297788
  0.90490519  0.90183218  0.86001555  0.17732802  0.52309872  0.22432887
  0.99750198  0.19645552  0.89341424  0.64855031  0.01390069  0.87379732
  0.22368021  0.26585213  0.60843939  0.74559994  0.58640495  0.47085835
  0.87439869  0.28302425  0.58262191  0.03047021  0.63725987  0.39903248
  0.77868351  0.45142109  0.7013175   0.58332084  0.53226347  0.24446232
  0.95680714  0.56208046  0.38283968  0.98809987  0.81956823  0.48170822
  0.86376422  0.3113668   0.71538988  0.78346935  0.76092989  0.79074284
  0.0656774   0.30367193  0.01220948  0.92957712  0.11030973  0.37887348
  0.87261566  0.06345908  0.38160215  0.32552959  0.69877511  0.1403288
  0.65962466  0.64203195  0.45085474  0.82267962  0.8207419   0.90103881
  0.08011825  0.27774951  0.95322617  0.74773234]
float64
float32
>>> 

到這裡,已經基本瞭解numpy的使用了。接著下來,繼續學習下陣列的乘法:

基本運算


陣列的算術運算是按元素的。新的陣列被建立並且被結果填充。


>>> a = array( [20,30,40,50] )
>>> b = arange( 4 )
>>> b
array([0, 1, 2, 3])
>>> c = a-b
>>> c
array([20, 29, 38, 47])
>>> b**2
array([0, 1, 4, 9])
>>> 10*sin(a)
array([ 9.12945251, -9.88031624,  7.4511316 , -2.62374854])
>>> a<35
array([True, True, False, False], dtype=bool)
不像許多矩陣語言,NumPy中的乘法運算子 * 指示按元素計算,矩陣乘法可以使用 dot 函式或建立矩陣物件實現(參見教程中的矩陣章節)


>>> A = array( [[1,1],
...             [0,1]] )
>>> B = array( [[2,0],
...             [3,4]] )
>>> A*B                         # elementwise product
array([[2, 0],
       [0, 4]])
>>> dot(A,B)                    # matrix product
array([[5, 4],
       [3, 4]])
有些操作符像 += 和 *= 被用來更改已存在陣列而不建立一個新的陣列。


>>> a = ones((2,3), dtype=int)
>>> b = random.random((2,3))
>>> a *= 3
>>> a
array([[3, 3, 3],
       [3, 3, 3]])
>>> b += a
>>> b
array([[ 3.69092703,  3.8324276 ,  3.0114541 ],
       [ 3.18679111,  3.3039349 ,  3.37600289]])
>>> a += b                                  # b is converted to integer type
>>> a
array([[6, 6, 6],
       [6, 6, 6]])
當運算的是不同型別的陣列時,結果陣列和更普遍和精確的已知(這種行為叫做upcast)。


>>> a = ones(3, dtype=int32)
>>> b = linspace(0,pi,3)
>>> b.dtype.name
'float64'
>>> c = a+b
>>> c
array([ 1.        ,  2.57079633,  4.14159265])
>>> c.dtype.name
'float64'
>>> d = exp(c*1j)
>>> d
array([ 0.54030231+0.84147098j, -0.84147098+0.54030231j,
       -0.54030231-0.84147098j])
>>> d.dtype.name
'complex128' 許多非陣列運算,如計算陣列所有元素之和,被作為ndarray類的方法實現


>>> a = random.random((2,3))
>>> a
array([[ 0.6903007 ,  0.39168346,  0.16524769],
       [ 0.48819875,  0.77188505,  0.94792155]])
>>> a.sum()
3.4552372100521485
>>> a.min()
0.16524768654743593
>>> a.max()
0.9479215542670073
這些運算預設應用到陣列好像它就是一個數字組成的列表,無關陣列的形狀。然而,指定 axis 引數你可以吧運算應用到陣列指定的軸上:


>>> b = arange(12).reshape(3,4)
>>> b
array([[ 0,  1,  2,  3],
       [ 4,  5,  6,  7],
       [ 8,  9, 10, 11]])
>>>
>>> b.sum(axis=0)                            # sum of each column
array([12, 15, 18, 21])
>>>
>>> b.min(axis=1)                            # min of each row
array([0, 4, 8])
>>>
>>> b.cumsum(axis=1)                         # cumulative sum along each row
array([[ 0,  1,  3,  6],
       [ 4,  9, 15, 22],
       [ 8, 17, 27, 38]])

1. C++標準模板庫從入門到精通 

2.跟老菜鳥學C++

3. 跟老菜鳥學python

4. 在VC2015裡學會使用tinyxml庫

5. 在Windows下SVN的版本管理與實戰 

7.在VC2015裡使用protobuf協議

8.在VC2015裡學會使用MySQL資料庫