NumPy
NumPy主要的內容操作是陣列(Array)。陣列物件名稱為ndarray。numpy1.py
- 欲使用NumPy,需先import numpy,使用化名(alias) np來減少打字長度。
- 建立一個array a,arange(15)意思為產生15個數字(0-14),reshape(3,5)意思為3個row,5個column。
- a.shape: a的形狀(row, col)。
- a.ndim: a的dimension。
- a.dtype.name: a的資料型態。
- 使用astype改變型態,e.g. a = a.astype(float)
- a.itemsize: a中資料的位元數(bytes)>> int32/8=4。
- a.size: a的資料數量。
- type(a): a的物件型態。
陣列建立
- 建立陣列可以用以下方式:
- np.array([1,2,3]): 直接給值,小括號內僅接受一個參數(list),若是高次陣列,需將row的list(tuple)放入一個list(tuple)內,e.g. b = np.array([[1,2,3],[4,5,6]])。
- 若是給的內容為其他資料型態(float, str等),dtype會自動改變。也可自訂dtype,e.g. c = np.array([[1,2,3],[4,5,6]], dtype = complex)
- np.ones((2,3)): 產生全1陣列(row:2, col:3),參數為tuple。
- np.full((2,3), 7): 產生全為某值(7)之陣列(row:2, col:3),第一個參數為tuple。
- np.eye(3): 產生對角線為1,其他為0之陣列(row:3, col:3)。
- np.empty([2,2]): 產生隨機內容之陣列(row:2, col:2) or e.g. np.empty([2,2], dtype=int)。
- np.arange(3,33,5): 產生自3到33(不包含33)中每間隔5的數字組成之array >> array([ 3, 8, 13, 18, 23, 28])。
- np.arange()的第三個參數若省略則預設值為1。
- np.linspace(0,5,6): 產生0到5(包含0,5)之間的6個數字,前後兩數字間差距相同(等距)。
- np.random.random(3): 產生隨機實數(0-1)之陣列(row:1, col:3),若是高次陣列,參數須為list,e.g. np.random.random((3,3))。
- 也可使用np.random.rand(3)>> np.random.rand(2,3),其中參數不為tuple(list)。
- 也可使用reshape()來建立,e.g. np.random.rand(12).reshape((3,4))。
- 若要產生隨機整數,可使用 np.random.randint(30, size = (3,4)),array內的數值為小於30(包含0,不包含30)之整數。
- 若是兩數之間的整數,可使用np.random.randint(30, 100, size = (3,4))。 >> np.random.randint(low = 30, high = 100, size = (3,4))
- 產生隨機陣列或是隨機取得陣列內容:np.random.choice(), np.random.permutation()
- np.fromfunction(fun, shape): e.g. np.fromfunction(lambda x,y: x+y, (2,3))。 np.tile(A, reps): A當作tile,重複reps次數,e.g. np.tile([1,2], 3)或是np.tile([[1,2],[3,4],[5,6]],(3,4))。
- np.repeat(A, reps, axis = None): 將A重複reps次數,與tile不同。e.g. np.repeat([1,2], 3);np.repeat([[1,2],[3,4]], 2, axis = 0);np.repeat(2,3)。
- np.ones_like(A): size與A相同的ones。
- np.zeros_like(A): size與A相同的zeros。
- np.empty_like(A): size與A相同的empty。
- np.take(A, I): let A = [0,1,2,3,4,5],I = [0,2,5] >> np.take(A,I)。若A=np.arange(6),means it is an ndarray,we can also use A[I] directly.。
陣列內容取得
要取得陣列內容,需要根據其index,例如:- 編號自0開始。若給[0,1,3]表示要取得index=0,1,3之值,若有負數表示自後往前數,例如-1表示最後一個。
- 因為arr有兩向,上例中1為編號為1的row,2為編號為2的col。
Slicing
Slicing是切片的意思,也就是取得一部分的array內容。
numpy1.py
- ar[3:9]表示取得index自3到9(不包含)中的所有數值,並傳回一個array。
- ar[1:7:2]表示取得index自1到7(不包含)中每間隔2的所有數值,並傳回一個array。
- ar[:7:3]表示取得index自0到7(不包含)中每間隔3的所有數值,並傳回一個array,冒號前若沒輸入表示自0開始,冒號後若沒輸入表示到最後都包含。
- ar[::2]表示取得index自0到最後每間隔2的所有數值,並傳回一個array。
- 若是2D則輸入兩個參數,e.g. a[:2,1:3]。
- a[0,:]表示index為0的row中所有數值。
- a[:,0]表示所有的row中index為0的值。
- a[a>3]表示取得a中所有大於3值,並傳回一個array。
- 若是僅a>3,則傳回一個boolean array,判斷元素是否>3。
Basic Operations
- 陣列的基本運算,例如加減乘除等,首先建立兩個array:
- x+y: 陣列相加,亦可使用np.add(x,y)。
- x-y: 陣列相減,亦可使用np.subtract(x,y)。
- x*y: 陣列相乘,亦可使用np.multiply(x,y)。
- x/y: 陣列相乘,亦可使用np.divide(x,y)。
- x**y: x的y次方。
- x+=1,x-=1,x*=2,x=x/2, x**=2: 元素+1,-1,*2,/2,**2。
-
let z = np.array([1,1]), what is x+z?。
-
請注意此處的相乘為對應元素相乘,而非矩陣的內積。
- 使用函數:
- np.sqrt(x): 平方根。
- np.sin(x): 取得sin。其他三角函數用法相同。
- np.log(x): 對數。
- np.exp(x): e的次方。
- np.min(x)或x.min(): 最小值。
- np.min(x, axis=0)或x.min(axis=0)與np.min(x, axis=1)或x.min(axis=1)表示x與y軸的最小值。
- max,sum,mean,std用法相同。
- 使用np.apply_along_axis(np.min, axis = 0, arr = x)可得到與np.min(x, 0)相同的效果,不過apply_along_axis()的第一個參數可以使用自訂函數:
- See also: all, any, argmax, argmin,argsort, average, bincount, ceil, clip, conj, cross, cumprod, diff, floor, lexsort, maximum, minimum, nonzero, outer, ptp, round, searchsorted, sort, trace, vectorize, where。
- 矩陣運算
- np.dot(x,y)或x.dot(y): dot product of two arrays。
- np.cross(x,y): cross product of two arrays。
- x.T或np.transpose(x)或x.transpose(): x的轉置矩陣。
- 使用swapaxes, e.g.np.swapaxes(x,0,1)或x.swapaxes(0,1)
- np.inner(x,y): inner product of two arrays。
- np.vdot(x,y): dot product of two vectors。
- np.outer(x,y): outer product of two vectors。
- See also: diagonal, choose, compress, cumsum, fill, imag, prod, put, putmask, real, svd, vdot。
- Statistics: cov, mean, sta, var, median, corrcoef。
-
請注意np.dot(x,y)與np.dot(y,x)不同。
Iterating & Stack
- 使用loop來逐一取得array內容,先建立一個array:
- 逐一取得row:
- 逐一取得元素。
- x.flat表示A 1-D iterator over the array,形成一個1-D的iterator。
- 使用x.flatten()傳回1-dimension array,等同於x.ravel(),也可以使用x.shape=(9)。
- 使用x.reshape(1,9)跟x.ravel()不同,傳回的是array([[1, 2, 3, 4, 5, 6, 7, 8, 9]]),要得到相同效果需使用:
- np.resize(x,(1,9))可得到與x.reshape(1,9)相同的array。
- 使用vstack()與hstack()來疊加兩個array:
- v為垂直向,h為平行向,堆疊方向的shape需相同。
- 亦可使用np.row_stack((x,y))與np.column_stack((x,y))來替代np.vstack((x,y)),np.vstack((x,y))。
- 也可使用np.concatenate((x,y),axis=0)與np.concatenate((x,y),axis=1)來達到相同效果。
- 若是使用np.concatenate((x,y),axis = None),如此又會得到與np.hstack((x.ravel(), y.ravel()))相同結果。
- 上一節討論如何將兩個陣列合一(使用stack),此處討論如何將其拆分,首先建立array。
- vsplit(x, 2)與hsplit(x, 2)的意思是將x中分,v代表第一軸(x向),h代表第二軸(y向),即使是要切分高次陣列,也是指第一跟第二軸。
- 若不是中分(或者切分方向並非偶數無法中分),可將第二個參數改為list(tuple),e.g.
- np.hsplit(x,[1,])表示切分為第1個column(index = 0)與其他(index = 1,2,3)。
- np.hsplit(x,(1,2))表示切分第1個column(index = 0),第二個column(index = 1)與其他(index = 2,3)。
- 可以直接使用np.split(x, [1,2], axis = 0)來切分,只要註明切分哪一軸即可。
- 使用dsplit來切分第三軸,e.g.
Split
View & Copy
- 當我們用等號assign一個array給另一個變數,只是讓另一個變數只位向該array,並沒有創造另一個array。e.g.
- 使用y = x, z = x.view()都會建立一個相同的物件指向同一個array,且其id相同 。
- 使用w = x[:,:]雖建立id不同之物件,但依然指位向同一個array,當改變x內之值(x[0,0] = 100),可見所有皆跟著改變。
- 若是要在記憶體內建立新的array,需使用copy指令,e.g. 三種寫法都可以,此時x與xx指向不同array(雖然內容相同),修改其中任一個並不會影響另一個array內容。
Save & Load File
- 可以使用np的指令輕鬆將array存成檔案或是自檔案取得。
- 使用np.save('filename', arrayname)來儲存array至檔案。
- 使用np.load('filename')自檔案讀取資料。
- 也可以使用np.savetxt("test.txt", data)與np.loadtxt("test.txt")來存儲與取得資料。
讀取文字檔
- 假定有一個名為somedata.csv的檔案,內容如下:
somedata.csv
- 要取得其中內容,可使用sdata = np.genfromtxt('somedata.csv', delimiter = ',', names = True)指令。
- 第三個參數names = True表示擷取第一行為標頭文字,若是僅使用sdata = np.genfromtxt('somedata.csv', delimiter = ','),表示沒有標頭文字。
- 若是原檔案沒有標頭文字,而取得內容後想要有標頭文字,則可使用sdata = np.genfromtxt('somedata.csv', delimiter = ',', names = 'id, x, y, demand, working time')這方式。
- 若是使用sdata = np.genfromtxt('somedata.csv', delimiter = ',', skip_header = 2, names = True)則表示跳過2行,使用skip_footer=1來跳過後面的1行。。
- 若是要改變資料型態,可使用sdata = np.genfromtxt('somedata.csv', delimiter = ',', names = True, dtype = int)
- 使用sdata = np.genfromtxt('somedata.csv', delimiter = ',', names = True, usecols = (1,2))來取得特定的column,若是有標頭文字,可使用標頭文字代替,e.g. sdata = np.genfromtxt('somedata.csv', delimiter = ',', names = True, usecols = ('x','y'))