欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

python科學(xué)計(jì)算之numpy——ufunc函數(shù)用法

 更新時(shí)間:2019年11月25日 15:05:38   作者:NeverMore_7  
今天小編就為大家分享一篇python科學(xué)計(jì)算之numpy——ufunc函數(shù)用法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧

寫(xiě)在前面

ufunc是universal function的縮寫(xiě),意思是這些函數(shù)能夠作用于narray對(duì)象的每一個(gè)元素上,而不是針對(duì)narray對(duì)象操作,numpy提供了大量的ufunc的函數(shù)。這些函數(shù)在對(duì)narray進(jìn)行運(yùn)算的速度比使用循環(huán)或者列表推導(dǎo)式要快很多,但請(qǐng)注意,在對(duì)單個(gè)數(shù)值進(jìn)行運(yùn)算時(shí),python提供的運(yùn)算要比numpy效率高。

四則運(yùn)算

numpy提供的四則ufunc有如下一些:

numpy提供的四則運(yùn)算unfunc能夠大大的提高計(jì)算效率,但如果運(yùn)算式復(fù)雜,且參與運(yùn)算的narray過(guò)大,會(huì)產(chǎn)生大量的中間結(jié)果,從而降低計(jì)算效率。例如:計(jì)算x=a*b+c時(shí),實(shí)際上會(huì)按照如下方式計(jì)算:

t = a*b 
x = t+c 
del t

這會(huì)產(chǎn)生兩次內(nèi)存分配,一次時(shí)x,一次時(shí)t,所以按照

x = a*b 
x = x+c

會(huì)節(jié)省一次內(nèi)存的分配,從而提高效率。

比較運(yùn)算 & bool運(yùn)算

numpy同時(shí)提供了=、<、>等這些比較運(yùn)算符,這些運(yùn)算符的結(jié)果是bool值或者bool數(shù)組。

np.array([1,2,3]) < np.array([0,3,4])
array([False, True, True], dtype=bool)

邏輯運(yùn)算and、or、not、xor等由于python提供了,所以numpy的這些邏輯運(yùn)算符是以logical_開(kāi)頭的函數(shù)

a = np.arange(5)
b= np.arange(4,-1,-1)
## print a==b
[False False True False False]
## print a>b
[False False False True True]
## print np.logical_or(a == b, a > b)
[False False True True True]

對(duì)兩個(gè)bool數(shù)組進(jìn)行邏輯運(yùn)算時(shí),將發(fā)生ValueError異常,因?yàn)閎ool值也是True和False,numpy無(wú)法確定運(yùn)算目的,可以使用numpy.any()和numpy.all()函數(shù),他們的使用方法和python的any()、all()函數(shù)用法相同。以bitwise_開(kāi)頭的函數(shù)時(shí)用于位運(yùn)算,如(bitwise_and、bitwise_or)等,也可以使用&、|、~和^來(lái)進(jìn)行運(yùn)算。

除了numpy提供的內(nèi)置ufunc函數(shù),用戶也可以編寫(xiě)自定義的ufunc函數(shù),方式是:

1. 編寫(xiě)對(duì)單個(gè)數(shù)值計(jì)算的目的函數(shù);

2. 利用np.frompyfunc(func, nin, nout)將其轉(zhuǎn)換為ufunc函數(shù),其中func是上面編寫(xiě)的目的函數(shù),nin是輸入的參數(shù)個(gè)數(shù),nout是返回值的個(gè)數(shù)。

## 基本形式
u_func = np.frompyfunc(func,nin,nout)
ret = u_func(narray_obj,param1,param2..)

這里返回的ret是object類型,所以實(shí)際上需要用astype()轉(zhuǎn)換為目的類型。numpy.vectorize()也實(shí)現(xiàn)了和numpy.frompyfunc()一樣的功能,區(qū)別是前者可以t通過(guò)otypes指定返回值的類型,不用再用astype()進(jìn)行轉(zhuǎn)換。

## 基本形式
u_func = np.frompyfunc(func,otypes=[dtype1,dtype2..]
ret = u_func(narray_object,param1,param2..)

廣播

先看個(gè)例子:

a = np.arange(0,60,10).reshape(-1,1)
b = np.arange(0,5)
#a
array([[ 0],
  [10],
  [20],
  [30],
  [40],
  [50]])
#b
array([0, 1, 2, 3, 4])

ok,現(xiàn)在計(jì)算a+b,不過(guò)現(xiàn)在有一個(gè)問(wèn)題,a和b的維度不一樣,那應(yīng)該怎么加?先看看結(jié)果吧

# a+b
array([[ 0, 1, 2, 3, 4],
  [10, 11, 12, 13, 14],
  [20, 21, 22, 23, 24],
  [30, 31, 32, 33, 34],
  [40, 41, 42, 43, 44],
  [50, 51, 52, 53, 54]])

結(jié)果來(lái)看,是用a的每一行的元素(這里a為列向量,每一行只有一個(gè)元素)與b的每一個(gè)元素相加,相當(dāng)于:

a=array([[ 0, 0, 0, 0, 0],
  [10, 10, 10, 10, 10],
  [20, 20, 20, 20, 20],
  [30, 30, 30, 30, 30],
  [40, 40, 40, 40, 40],
  [50, 50, 50, 50, 50]])

而b是一個(gè)行向量,現(xiàn)在我們將這一個(gè)行向量重復(fù)6次,和a的第0軸長(zhǎng)度相同,構(gòu)成一個(gè)二維數(shù)組,相當(dāng)于:

b=array([[0, 1, 2, 3, 4],
  [0, 1, 2, 3, 4],
  [0, 1, 2, 3, 4],
  [0, 1, 2, 3, 4],
  [0, 1, 2, 3, 4],
  [0, 1, 2, 3, 4]])

現(xiàn)在,再進(jìn)行相加,自然就是對(duì)用元素相加了,也就是上面的結(jié)果,這就是numpy中的廣播,對(duì)進(jìn)行運(yùn)算的兩個(gè)narray對(duì)象shape不一樣時(shí),進(jìn)行的維度補(bǔ)齊??偟膩?lái)說(shuō),numpy的廣播規(guī)則基于下面4個(gè)規(guī)則:

讓所有輸入數(shù)姐都向其中維數(shù)最多的數(shù)組看齊,shape屬性中不足的部分都通過(guò)在前面加1補(bǔ)齊; 如上面的輸入中,a.shape=(6,1),b.shape=(,5),a的維數(shù)是2,b的維數(shù)是1,所以b向a看齊,并且用1補(bǔ)齊,那么b.shape=(1,5)。

輸出數(shù)組的shape屬性是輸入數(shù)組的shape屬性的各個(gè)軸上的最大值 輸出是各軸上最大值,所以a+b的輸出的shape應(yīng)該是(6,5);

如果輸入數(shù)組的某個(gè)軸的長(zhǎng)度 為 1或與輸出數(shù)組的對(duì)應(yīng)軸的長(zhǎng)度相同,這個(gè)數(shù)組能夠用來(lái)計(jì)算,否則出錯(cuò)

當(dāng)輸入數(shù)組的某個(gè)軸的長(zhǎng)度為1吋,沿著此軸運(yùn)算時(shí)都用此軸上的第一組值

由于廣播在numpy計(jì)算中比較常見(jiàn),所以numpy提供了ogrid和mgrid來(lái)創(chuàng)建廣播計(jì)算的數(shù)組,前者返回的是兩個(gè)向量,后者返回的是進(jìn)行廣播運(yùn)算的數(shù)組。

x,y = np.ogrid[:5,:5]
# x
array([[0],
  [1],
  [2],
  [3],
  [4]])
# y
array([[0, 1, 2, 3, 4]])
x,y=np.mgrid[:5,:5]
# x
[[0, 0, 0, 0, 0],
[1, 1, 1, 1, 1],
[2, 2, 2, 2, 2],
[3, 3, 3, 3, 3],
[4, 4, 4, 4, 4]]
#y
[[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4],
[0, 1, 2, 3, 4]]]

ogrid[]參數(shù)是有兩種形式(1):[start:end:step]即起點(diǎn)、終點(diǎn)和步長(zhǎng);(2):[start:end:len]即起點(diǎn)、終點(diǎn)和數(shù)組長(zhǎng)度,這里的長(zhǎng)度為了和步長(zhǎng)區(qū)分,在傳入時(shí)時(shí)以虛數(shù)方式傳入的,例如[1,5,4j]將產(chǎn)生[1,2,3,4]這樣的數(shù)組。

另外廣播支持特殊的下標(biāo)None,意義時(shí)在對(duì)應(yīng)位置上產(chǎn)生1的新軸,例如a[None,:]等效于a.reshape((1,-1)),a[:,None]等效于a.reshape((-1,1)),另外,np.ix_()能將一維數(shù)組轉(zhuǎn)換為能進(jìn)行廣播的二維數(shù)組:

x=np.array([0,1,4,10])
y=np.array([2,3,8])
gy,gx=np.ix_(y,x)
#print gy
[[2]
[3]
[8]]
#print gx
[[ 0 1 4 10]]
# gx+gy
array([[ 2, 3, 6, 12],
  [ 3, 4, 7, 13],
  [ 8, 9, 12, 18]])

np.ix_()支持多個(gè)參數(shù),從而支持n維空間的廣播計(jì)算。

ufunc方法

ufunc函數(shù)對(duì)象本身還有一些方法函數(shù),這些方法只對(duì)兩個(gè)輸入、一個(gè)輸出的ufunc 函數(shù)有效,其他的ufunc對(duì)象調(diào)用這些方法時(shí)會(huì)拋出ValueError異常。

(1). reduce(),沿著指定軸對(duì)數(shù)組進(jìn)行操作,相當(dāng)于將相應(yīng)的操作放到該軸元素之間。

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()類似,區(qū)別時(shí)是前者會(huì)保留中間結(jié)果:

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=1) 
#
array([[ 1, 3, 6],
  [ 4, 9, 15]])

(3). reduceat()方法計(jì)算多紐reduce()的結(jié)果,通 過(guò) indices參數(shù)指定一系列的起始和終止位置。它的計(jì)算有些特別,,計(jì)算的方法如下:

if indices[i] < indices[i+1]:
 result[i] = <op>.reduce(a[indices[i]:indices[i+1]])
else:
 result[i] = a[indices[i]]
#result[-1]的計(jì)算如下:
<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])

## 計(jì)算過(guò)程如下:
 : a[0] -> 1
 : a[1] -> 2
 : a[0] + a[1] -> 1 + 2
 : a[2] -> 3
 : a[0] + a[1] + a[2] -> 1 + 2 + 3 = 6
 : a[3] -> 4
 :a[0] + a[1] + a[2] + a[4] - > 1 + 2 + 3 + 4 = 1 0

再看多維數(shù)組

在前一篇文章中我們提到過(guò)多維數(shù)組,現(xiàn)在我們回頭再看看多維數(shù)組的下標(biāo)取數(shù)據(jù)。首先,多維數(shù)組的下標(biāo)應(yīng)該是一個(gè)長(zhǎng)度和數(shù)組的維數(shù)相同的元組。如栗下標(biāo)元組的長(zhǎng)度比數(shù)組的維數(shù)大,就會(huì)出錯(cuò);如果小,就 會(huì) 在 下 標(biāo) 元 組 的 后 而 補(bǔ) ,使得它的長(zhǎng)度與數(shù)組維數(shù)相同。如果下標(biāo)對(duì)象不是元組,則 numpy會(huì)首先把它轉(zhuǎn)換為元組。這種轉(zhuǎn)換可能會(huì)和用戶所希望的不一致,因此為了避免出現(xiàn)問(wèn)題,請(qǐng) “顯式”地使用元組作為下標(biāo)。

a = np.arange(3*4*5).reshape(3,4,5)
array([[[ 0, 1, 2, 3, 4],
  [ 5, 6, 7, 8, 9],
  [10, 11, 12, 13, 14],
  [15, 16, 17, 18, 19]],

  [[20, 21, 22, 23, 24],
  [25, 26, 27, 28, 29],
  [30, 31, 32, 33, 34],
  [35, 36, 37, 38, 39]],

  [[40, 41, 42, 43, 44],
  [45, 46, 47, 48, 49],
  [50, 51, 52, 53, 54],
  [55, 56, 57, 58, 59]]])

lidx=[[0],[1]]
#a[lidx]

aidx = np.array(lidx)
#a[aidx]
array([[[[ 0, 1, 2, 3, 4],
   [ 5, 6, 7, 8, 9],
   [10, 11, 12, 13, 14],
   [15, 16, 17, 18, 19]]],


  [[[20, 21, 22, 23, 24],
   [25, 26, 27, 28, 29],
   [30, 31, 32, 33, 34],
   [35, 36, 37, 38, 39]]]])

可以看到,numpy把列表[[0],[1]]轉(zhuǎn)換成元組([0],[1]),而把數(shù)組對(duì)象轉(zhuǎn)換成(aidx,:,:)。

整數(shù)數(shù)組和切片做為下標(biāo)

如果利用數(shù)組作為下標(biāo),但數(shù)組的維度都不一樣,那么這個(gè)時(shí)候這些數(shù)組將會(huì)應(yīng)用廣播規(guī)則把這些數(shù)組轉(zhuǎn)換成一樣,轉(zhuǎn)換的規(guī)則是上面說(shuō)到的先用1補(bǔ)足然后取各個(gè)維度的最大值。

i0 = np.array([[1,2,1],[0,1,0]])
i1 = np.array([[[0]],[[1]]])
i2 = np.array([[[2,3,2]]])
#print i0.shape
(2, 3)
#print i1.shape
(2, 1, 1)
#print i2.shape
(1, 1, 3)
# i0補(bǔ)齊之后為 (1,2,3),然后取最大值為
(2,2,3)

這里將所有的數(shù)組進(jìn)行廣播,把所有的數(shù)組轉(zhuǎn)換成shape=(2,2,3),利用numpy.broadcast_arrays()可以查看廣播后的數(shù)組:

id0,id1,id2=np.broadcast_arrays(i0,i1,i2)
#id0
[[[1 2 1]
 [0 1 0]]

 [[1 2 1]
 [0 1 0]]
#id1
[[[0 0 0]
 [0 0 0]]

 [[1 1 1]
 [1 1 1]]]
#id2
[[[2 3 2]
 [2 3 2]]

 [[2 3 2]
 [2 3 2]]]

然后利用下標(biāo)取元素時(shí),例如i,j,k=1,1,1時(shí),取得的元素應(yīng)該是a[id0[i,j,k],id1[i,j,k],id2[i,j,k]]=a[1,1,3]=28。下標(biāo)中含有切片時(shí),首先來(lái)看第一種,就是整數(shù)數(shù)組時(shí)連續(xù)的,也就是數(shù)組之間沒(méi)有切片,例如a[1:3,i0,i1],這種情況下,首先會(huì)把整數(shù)數(shù)組(i0,i1)廣播,然后將切片的長(zhǎng)度放到相應(yīng)的位置構(gòu)成一個(gè)維度,i0,i1廣播后的shape=(2,2,3),切片的長(zhǎng)度為2,所以最后的shape=(2,2,2,3)。最后的結(jié)果是a[1:3,id0[i,j,k],id1[i,j,k]]。再者,如果切片是再整數(shù)數(shù)組之間,那么同樣會(huì)將數(shù)組廣播,然后把切片位置替換為數(shù)組的維度或者切片的長(zhǎng)度添加到索引的最后面,如a[i0,:,i1],i0,i1廣播后的shape=(2,2,3),數(shù)組a的第二個(gè)軸的長(zhǎng)度為4,所以最后的shape=(2,2,3,4)。

bool數(shù)組做為下標(biāo)

用bool數(shù)組作為下標(biāo)時(shí),會(huì)將bool數(shù)組中為T(mén)rue的索引組成一個(gè)整數(shù)數(shù)組,然后以此數(shù)組作為下標(biāo)。相當(dāng)于用numpy.nonzero(bool_array)的結(jié)果,例如:

b2 = np.array([[True,False,True],[True,False,False]])
np.nonzero(b2)
##
(array([0, 0, 1]), array([0, 2, 0]))
## ## ## ## ## ## ## ## ## ## ## ## ## ## ## ## 
## 相當(dāng)于取[0,0],[0,2],[1,0]

除此之外,如果bool數(shù)組中有切片,那么相當(dāng)于將bool值轉(zhuǎn)換成nonzero()后的整數(shù)數(shù)組,切片位置不變。

以上這篇python科學(xué)計(jì)算之numpy——ufunc函數(shù)用法就是小編分享給大家的全部?jī)?nèi)容了,希望能給大家一個(gè)參考,也希望大家多多支持腳本之家。

相關(guān)文章

  • TensorFlow人工智能學(xué)習(xí)按索引取數(shù)據(jù)及維度變換詳解

    TensorFlow人工智能學(xué)習(xí)按索引取數(shù)據(jù)及維度變換詳解

    這篇文章主要為大家介紹了TensorFlow人工智能學(xué)習(xí)按索引取數(shù)據(jù)及維度變換的示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助
    2021-11-11
  • OpenCV實(shí)戰(zhàn)案例之車(chē)道線識(shí)別詳解

    OpenCV實(shí)戰(zhàn)案例之車(chē)道線識(shí)別詳解

    計(jì)算機(jī)視覺(jué)在自動(dòng)化系統(tǒng)觀測(cè)環(huán)境、預(yù)測(cè)該系統(tǒng)控制器輸入值等方面起著至關(guān)重要的作用,下面這篇文章主要給大家介紹了關(guān)于OpenCV實(shí)戰(zhàn)案例之車(chē)道線識(shí)別的相關(guān)資料,需要的朋友可以參考下
    2022-10-10
  • python中的變量命名規(guī)則詳情

    python中的變量命名規(guī)則詳情

    這篇文章主要介紹了python中的變量命名規(guī)則詳情,變量名可以包括字母、數(shù)字、下劃線,但是數(shù)字不能做為開(kāi)頭,變量用的好或不好,和代碼質(zhì)量有著非常重要的聯(lián)系,合理的使用變量,可以讓你的代碼可讀性更高并且更加簡(jiǎn)潔,下面相關(guān)內(nèi)容吧需要的小伙伴可以參考一下
    2022-03-03
  • pytorch中的matmul與mm,bmm區(qū)別說(shuō)明

    pytorch中的matmul與mm,bmm區(qū)別說(shuō)明

    這篇文章主要介紹了pytorch中的matmul與mm,bmm區(qū)別說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-05-05
  • 11個(gè)Python Pandas小技巧讓你的工作更高效(附代碼實(shí)例)

    11個(gè)Python Pandas小技巧讓你的工作更高效(附代碼實(shí)例)

    這篇文章主要介紹了11個(gè)Python Pandas小技巧讓你的工作更高效(附代碼實(shí)例),小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,也給大家做個(gè)參考。一起跟隨小編過(guò)來(lái)看看吧
    2019-04-04
  • python實(shí)現(xiàn)石頭剪刀布程序

    python實(shí)現(xiàn)石頭剪刀布程序

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)石頭剪刀布程序,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2019-01-01
  • python區(qū)塊鏈簡(jiǎn)易版交易完善挖礦獎(jiǎng)勵(lì)示例

    python區(qū)塊鏈簡(jiǎn)易版交易完善挖礦獎(jiǎng)勵(lì)示例

    這篇文章主要介紹了python區(qū)塊鏈簡(jiǎn)易版交易完善挖礦獎(jiǎng)勵(lì)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪
    2022-05-05
  • Python面向?qū)ο蟪绦蛟O(shè)計(jì)示例小結(jié)

    Python面向?qū)ο蟪绦蛟O(shè)計(jì)示例小結(jié)

    這篇文章主要介紹了Python面向?qū)ο蟪绦蛟O(shè)計(jì),結(jié)合實(shí)例形式總結(jié)分析了Python面向?qū)ο蟪绦蛟O(shè)計(jì)中比較常見(jiàn)的類定義、實(shí)例化、繼承、私有變量等相關(guān)使用技巧與操作注意事項(xiàng),需要的朋友可以參考下
    2019-01-01
  • PyQt5類型判定+對(duì)象刪除操作

    PyQt5類型判定+對(duì)象刪除操作

    這篇文章主要介紹了PyQt5類型判定+對(duì)象刪除操作,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),感興趣的朋友跟隨小編一起看看吧
    2024-06-06
  • python實(shí)時(shí)監(jiān)控cpu小工具

    python實(shí)時(shí)監(jiān)控cpu小工具

    這篇文章主要為大家詳細(xì)介紹了python實(shí)時(shí)監(jiān)控cpu的小工具,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-06-06

最新評(píng)論