Numpy簡單介紹
1.Numpy是什么
很簡單,Numpy是Python的一個科學計算的庫,提供了矩陣運算的功能,其一般與Scipy、matplotlib一起使用。其實,list已經提供了類似於矩陣的表示形式,不過numpy為我們提供了更多的函數。如果接觸過matlab、scilab,那么numpy很好入手。 在以下的代碼示例中,總是先導入了numpy:(通用做法import numpu as np 簡單輸入)
>>> import numpy as np >>> print np.version.version 1.6.2
2. 多維數組
多維數組的類型是:numpy.ndarray。
使用numpy.array方法
以list或tuple變量為參數產生一維數組:
>>> print np.array([1,2,3,4]) [1 2 3 4] >>> print np.array((1.2,2,3,4)) [ 1.2 2. 3. 4. ] >>> print type(np.array((1.2,2,3,4))) <type 'numpy.ndarray'>
以list或tuple變量為元素產生二維數組或者多維數組:
>>> x = np.array(((1,2,3),(4,5,6))) >>> x array([[1, 2, 3], [4, 5, 6]]) >>> y = np.array([[1,2,3],[4,5,6]]) >>> y array([[1, 2, 3], [4, 5, 6]])
numpy數據類型設定與轉換
numpy ndarray數據類型可以通過參數dtype 設定,而且可以使用astype轉換類型,在處理文件時候這個會很實用,注意astype 調用會返回一個新的數組,也就是原始數據的一份拷貝。
numeric_strings2 = np.array(['1.23','2.34','3.45'],dtype=np.string_) numeric_strings2 Out[32]: array(['1.23', '2.34', '3.45'], dtype='|S4') numeric_strings2.astype(float) Out[33]: array([ 1.23, 2.34, 3.45])
numpy索引與切片
index 和slicing :第一數值類似數組橫坐標,第二個為縱坐標
1 >>> x[1,2] 2 6 3 >>> y=x[:,1] 4 >>> y 5 array([2, 5])
涉及改變相關問題,我們改變上面y是否會改變x?這是特別需要關注的!
1 >>> y 2 array([2, 5]) 3 >>> y[0] = 10 4 >>> y 5 array([10, 5]) 6 >>> x 7 array([[ 1, 10, 3], 8 [ 4, 5, 6]])
通過上面可以發現改變y會改變x ,因而我們可以推斷,y和x指向是同一塊內存空間值,系統沒有為y 新開辟空間把x值賦值過去。
1 arr = np.arange(10) 2 3 arr 4 Out[45]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9]) 5 6 arr[4] 7 Out[46]: 4 8 9 arr[3:6] 10 Out[47]: array([3, 4, 5]) 11 12 arr[3:6] = 12 13 14 arr 15 Out[49]: array([ 0, 1, 2, 12, 12, 12, 6, 7, 8, 9])
如上所示:當將一個標量賦值給切片時,該值會自動傳播整個切片區域,這個跟列表最重要本質區別,數組切片是原始數組的視圖,視圖上任何修改直接反映到源數據上面。
思考為什么這么設計? Numpy 設計是為了處理大數據,如果切片采用數據復制話會產生極大的性能和內存消耗問題。
假如說需要對數組是一份副本而不是視圖可以如下操作:
1 arr_copy = arr[3:6].copy() 2 3 arr_copy[:]=24 4 5 arr_copy 6 Out[54]: array([24, 24, 24]) 7 8 arr 9 Out[55]: array([ 0, 1, 2, 12, 12, 12, 6, 7, 8, 9])
再看下對list 切片修改
1 l=range(10) 2 3 l 4 Out[35]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9] 5 6 l[5:8] = 12 7 Traceback (most recent call last): 8 9 File "<ipython-input-36-022af3ddcc9b>", line 1, in <module> 10 l[5:8] = 12 11 12 TypeError: can only assign an iterable 13 14 15 l1= l[5:8] 16 17 l1 18 Out[38]: [5, 6, 7] 19 20 l1[0]=12 21 22 l1 23 Out[40]: [12, 6, 7] 24 25 l 26 Out[41]: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
多維數組索引、切片
1 arr2d = np.arange(1,10).reshape(3,3) 2 3 arr2d 4 Out[57]: 5 array([[1, 2, 3], 6 [4, 5, 6], 7 [7, 8, 9]]) 8 9 arr2d[2] 10 Out[58]: array([7, 8, 9]) 11 12 arr2d[0][2] 13 Out[59]: 3 14 15 arr2d[0,2] 16 Out[60]: 3
布爾型索引
這種類型在實際代碼中出現比較多,關注下。
names = np.array(['Bob','joe','Bob','will']) names == 'Bob' Out[70]: array([ True, False, True, False], dtype=bool)
1 data 2 Out[73]: 3 array([[ 0.36762706, -1.55668952, 0.84316735, -0.116842 ], 4 [ 1.34023966, 1.12766186, 1.12507441, -0.68689309], 5 [ 1.27392366, -0.43399617, -0.80444728, 1.60731881], 6 [ 0.23361565, 1.38772715, 0.69129479, -1.19228023], 7 [ 0.51353082, 0.17696698, -0.06753478, 0.80448168], 8 [ 0.21773096, 0.60582802, -0.46446071, 0.83131122], 9 [ 0.50569072, 0.04431685, -0.69358155, -0.9629124 ]]) 10 11 data[data < 0] = 0 12 13 data 14 Out[75]: 15 array([[ 0.36762706, 0. , 0.84316735, 0. ], 16 [ 1.34023966, 1.12766186, 1.12507441, 0. ], 17 [ 1.27392366, 0. , 0. , 1.60731881], 18 [ 0.23361565, 1.38772715, 0.69129479, 0. ], 19 [ 0.51353082, 0.17696698, 0. , 0.80448168], 20 [ 0.21773096, 0.60582802, 0. , 0.83131122], 21 [ 0.50569072, 0.04431685, 0. , 0. ]])
上面展示通過布爾值來設置值的手段。
數組文件輸入輸出
在跑實驗時經常需要用到讀取文件中的數據,其實在numpy中已經有成熟函數封裝好了可以使用
將數組以二進制形式格式保存到磁盤,np.save 、np.load 函數是讀寫磁盤的兩個主要函數,默認情況下,數組以未壓縮的原始二進制格式保存在擴展名為.npy的文件中
1 arr = np.arange(10) 2 np.save('some_array',arr)
1 np.load('some_array.npy') 2 Out[80]: array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])
存取文本文件:
文本中存放是聚類需要數據,直接可以方便讀取到numpy array中,省去一行行讀文件繁瑣。
1 arr = np.loadtxt('dataMatrix.txt',delimiter=' ') 2 3 arr 4 Out[82]: 5 array([[ 1. , 1. , 1. , 1. , 1. , 6 0.8125 ], 7 [ 0.52882353, 0.56271186, 0.48220588, 0.53384615, 0.61651376, 8 0.58285714], 9 [ 0. , 0. , 0. , 1. , 1. , 10 1. ], 11 [ 1. , 0.92857143, 0.91857143, 1. , 1. , 12 1. ], 13 [ 1. , 1. , 1. , 1. , 1. , 14 1. ], 15 [ 0.05285714, 0.10304348, 0.068 , 0.06512821, 0.05492308, 16 0.05244898], 17 [ 0.04803279, 0.08203125, 0.05516667, 0.05517241, 0.04953488, 18 0.05591549], 19 [ 0.04803279, 0.08203125, 0.05516667, 0.05517241, 0.04953488, 20 0.05591549]])
np.savetxt 執行相反的操作,這兩個函數在跑實驗加載數據時可以提供很多便利!!!
使用numpy.arange方法
1 >>> print np.arange(15) 2 [ 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14] 3 >>> print type(np.arange(15)) 4 <type 'numpy.ndarray'> 5 >>> print np.arange(15).reshape(3,5) 6 [[ 0 1 2 3 4] 7 [ 5 6 7 8 9] 8 [10 11 12 13 14]] 9 >>> print type(np.arange(15).reshape(3,5)) 10 <type 'numpy.ndarray'>
使用numpy.linspace方法
例如,在從1到10中產生20個數:
1 >>> print np.linspace(1,10,20) 2 [ 1. 1.47368421 1.94736842 2.42105263 2.89473684 3 3.36842105 3.84210526 4.31578947 4.78947368 5.26315789 4 5.73684211 6.21052632 6.68421053 7.15789474 7.63157895 5 8.10526316 8.57894737 9.05263158 9.52631579 10. ]
使用numpy.zeros,numpy.ones,numpy.eye等方法可以構造特定的矩陣
1 >>> print np.zeros((3,4)) 2 [[ 0. 0. 0. 0.] 3 [ 0. 0. 0. 0.] 4 [ 0. 0. 0. 0.]] 5 >>> print np.ones((3,4)) 6 [[ 1. 1. 1. 1.] 7 [ 1. 1. 1. 1.] 8 [ 1. 1. 1. 1.]] 9 >>> print np.eye(3) 10 [[ 1. 0. 0.] 11 [ 0. 1. 0.] 12 [ 0. 0. 1.]]
獲取數組的屬性:
1 >>> a = np.zeros((2,2,2)) 2 >>> print a.ndim #數組的維數 3 3 4 >>> print a.shape #數組每一維的大小 5 (2, 2, 2) 6 >>> print a.size #數組的元素數 7 8 8 >>> print a.dtype #元素類型 9 float64 10 >>> print a.itemsize #每個元素所占的字節數 11 8
Memory layout
The following attributes contain information about the memory layout of the array:
Array methods
An ndarray object has many methods which operate on or with the array in some fashion, typically returning an array result. These methods are briefly explained below. (Each method’s docstring has a more complete description.)
For the following methods there are also corresponding functions in numpy: all, any, argmax, argmin, argpartition, argsort, choose, clip,compress, copy, cumprod, cumsum, diagonal, imag, max, mean, min, nonzero, partition, prod, ptp, put, ravel, real, repeat, reshape, round,searchsorted, sort, squeeze, std, sum, swapaxes, take, trace, transpose, var.
用到比較多函數示例:
1 >>> x 2 array([[[ 0, 1, 2], 3 [ 3, 4, 5], 4 [ 6, 7, 8]], 5 6 [[ 9, 10, 11], 7 [12, 13, 14], 8 [15, 16, 17]], 9 10 [[18, 19, 20], 11 [21, 22, 23], 12 [24, 25, 26]]]) 13 >>> x.sum(axis=1) 14 array([[ 9, 12, 15], 15 [36, 39, 42], 16 [63, 66, 69]]) 17 >>> x.sum(axis=2) 18 array([[ 3, 12, 21], 19 [30, 39, 48], 20 [57, 66, 75]])
1 >>> np.sum([[0, 1], [0, 5]]) 2 6 3 >>> np.sum([[0, 1], [0, 5]], axis=0) 4 array([0, 6]) 5 >>> np.sum([[0, 1], [0, 5]], axis=1) 6 array([1, 5])
合並數組
使用numpy下的vstack(垂直方向)和hstack(水平方向)函數:
1 >>> a = np.ones((2,2)) 2 >>> b = np.eye(2) 3 >>> print np.vstack((a,b)) 4 [[ 1. 1.] 5 [ 1. 1.] 6 [ 1. 0.] 7 [ 0. 1.]] 8 >>> print np.hstack((a,b)) 9 [[ 1. 1. 1. 0.] 10 [ 1. 1. 0. 1.]]
看一下這兩個函數有沒有涉及到淺拷貝這種問題:
1 >>> c = np.hstack((a,b)) 2 >>> print c 3 [[ 1. 1. 1. 0.] 4 [ 1. 1. 0. 1.]] 5 >>> a[1,1] = 5 6 >>> b[1,1] = 5 7 >>> print c 8 [[ 1. 1. 1. 0.] 9 [ 1. 1. 0. 1.]]
通過上面可以知道,這里進行是深拷貝,而不是引用指向同一位置的淺拷貝。
深拷貝數組
數組對象自帶了淺拷貝和深拷貝的方法,但是一般用深拷貝多一些:
1 >>> a = np.ones((2,2)) 2 >>> b = a 3 >>> b is a 4 True 5 >>> c = a.copy() #深拷貝 6 >>> c is a 7 False
基本的矩陣運算
轉置:
1 >>> a = np.array([[1,0],[2,3]]) 2 >>> print a 3 [[1 0] 4 [2 3]] 5 >>> print a.transpose() 6 [[1 2] 7 [0 3]]
numpy.linalg模塊中有很多關於矩陣運算的方法:
特征值、特征向量:
1 >>> a = np.array([[1,0],[2,3]]) 2 3 >>> nplg.eig(a) 4 (array([ 3., 1.]), array([[ 0. , 0.70710678], 5 [ 1. , -0.70710678]]))
完畢!更多精彩文章關注公眾號python社區營