ufunc函式(詳解 基礎學習 tcy)
阿新 • • 發佈:2019-01-22
ufunc函式 2018/11/22 # ufunc是universal function的縮寫,是一種能對陣列中每個元素進行操作的函式。 # Numpy內建的許多ufunc函式都是C語言實現的,計算速度非常快 ============================================================================== 1.說明: 計算單值建議採用Math庫函式,np.sin( )對應math.sin( );對於陣列元素,採用numpy庫函 讀取ndarray陣列中單個元素(下標獲取轉換為python標準型別耗時)a.item(1,2) #與a[1,2]類似 2.ufunc函式屬性方法 見備註 ============================================================================== 3.編寫自定義ufunc函式: # 基本形式 u_func = np.frompyfunc(func, nin, nout,otypes=[dtype1,dtype2..]#返回np.object u_func = np.vectorize(pyfunc, otypes=None, doc=None, excluded=None, cache=False,signature=None) # 第一步:定義函式 def MyAdd(x,y): return x+y # 第二步:轉換 uMyAdd =np.frompyfunc(MyAdd,2,1)#返回np.object型別,需要用a=a.astype()轉換為目的型別 uMyAdd1=np.vectorize(MyAdd,otypes=[np.int]) # 第三步:應用 a=np.array([1,2,3]) b=np.array([4,5,6]) c=uMyAdd(a,b) # array([5, 7, 9], dtype=object) c=c.astype(np.int) # array([5, 7, 9]) c.dtype # dtype('int32') d=uMyAdd1(a,b) # array([5, 7, 9]) d.dtype # dtype('int32') 備註: ======================================================================== ufunc函式引數 out #輸出 where #布林陣列。True值表示計算該位置的ufunc,False值表示僅在輸出中保留該值。 axes # 預設值是'same_kind' order #預設為'K'儘可能接近地匹配輸入的元素排序。 dtype keepdims#True則減小的軸將作為尺寸為1的尺寸保留在結果中,只用於對輸入操作通用ufunc subok # 預設為true。如果設定為false,則輸出將始終是嚴格的陣列,而不是子型別。 extobj #指定ufunc緩衝區大小 ======================================================================== 屬性(只讀) np.add.__name__#函式名稱 'add' np.add.__doc__ #函式文件 np.add.nin #輸入引數數量2 np.add.nout #輸出引數數量1 np.add.nargs #引數數量3 np.add.ntypes #型別數量22 np.add.types #包含型別列表 [?,b,B,h,H,i,I,l,L,q,Q,e,f,d,g,F,D,G,M,m,M,O] np.add.identity #身份價值0 np.add.signature#廣義ufunc操作的核心元素的定義 ======================================================================== ufunc方法 # ufunc函式方法只對兩個輸入、一個輸出的ufunc 函式有效,其他ufunc物件呼叫會ValueError ufunc.reduce(a[, axis, dtype, out, keepdims])#減少軸數 ufunc.accumulate(array[, axis, dtype, out]) #陣列元素累計計算 ufunc.reduceat(a, indices[, axis, dtype, out]) #在單個軸上使用指定切片執行(區域性)縮減 ufunc.outer(A, B, **kwargs)#Apply the ufunc op to all pairs (a, b) with a in A and b in B.將ufunc OP應用於a和b在B中的所有對(a,b) ufunc.at(a, indices[, b]) #對'index'指定的元素在運算元'a'上執行無緩衝的就地操作. (1). reduce()#沿著指定軸對陣列進行操作,相當於將相應的操作放到該軸元素之間。 np.add.reduce([1,2,3]) #1+2+3=6 np.add.reduce([[1,2,3],[4,5,6]]) #[1+4,2+5,3+6]=[5,7,9] np.add.reduce([[1,2,3],[4,5,6]],axis=1) #[1+2+3,4+5+6]=[6,15] (2). accumulate()#和reduce()類似,會保留中間結果: np.add.accumulate([1,2,3]) #[1,1+2,1+2+3]=[1,3,6] np.add.accumulate([[1,2,3],[4,5,6]],axis=0) #array([[1, 2, 3],[5, 7, 9]], dtype=int32) np.add.accumulate([[1,2,3],[4,5,6]],axis=1) #array([[ 1, 3, 6],[ 4, 9, 15]], dtype=int32) (3). reduceat()方法計算多維reduce()的結果#通過 indices引數指定一系列的起始和終止位置。它的計算有些特別,,計算的方法如下: if indices[i] < indices[i+1]: result[i] = <op>.reduce(a[indices[i]:indices[i+1]]) else: result[i] = a[indices[i]] #result[-1]的計算如下: <op>.reduce(a[indices[-1]:]) # 例: a = np.array([1,2,3,4]) result = np.add.reduceat(a, indices=[0,1,0,2,0,3,0]) ## result array([1,2,3,3,6,4,10]) ## 計算過程如下: 1 : a[0] -> 1 2 : a[1] -> 2 3 : a[0] + a[1] -> 1 + 2 4 : a[2] -> 3 5 : a[0] + a[1] + a[2] -> 1 + 2 + 3 = 6 6 : a[3] -> 4 7 : a[0] + a[1] + a[2] + a[4] - > 1 + 2 + 3 + 4 = 10 (4) ufunc.outer 將a的每個元素依次作用於b:通過函式 # 原理: C[i0,i1,...,i_m_1 ,j0,j1,...,j_n_1]=op(a[i0,i1,...,i_m_1],b[j0,j1,...,j_n_1]) # 對於a和b一維,這相當於: r = empty(len(a),len(b)) for i in range(len(a)): for j in range(len(b)): r[i,j] = op(a[i], b[j]) # op = ufunc in question a=np.array([1,2,3]) b=np.array([4,5,6]) np.add.outer(a,b) array([[5, 6, 7], #1+[4,5,6] [6, 7, 8], #2+[4,5,6] [7, 8, 9]])#3+[4,5,6] a=np.array([[1,2,3],[4,5,6]]) b=np.array([[11,12,13],[14,15,16]]) np.add.outer(a,b) array([[[[12, 13, 14], #1+[11,12,13] [15, 16, 17]], #1+[14,15,16] [[13, 14, 15], #2+[11,12,13] [16, 17, 18]], #2+[14,15,16] [[14, 15, 16], #3+[11,12,13] [17, 18, 19]]], #3+[14,15,16] [[[15, 16, 17], #4+[11,12,13] [18, 19, 20]], #4+[14,15,16] [[16, 17, 18], #5+[11,12,13] [19, 20, 21]], #5+[14,15,16] [[17, 18, 19], #6+[11,12,13] [20, 21, 22]]]])#6+[14,15,16] =====================================================================