實(shí)例詳解Python中的numpy.abs和abs函數(shù)
說(shuō)在最前
不知道小伙伴們?cè)趯?xiě)代碼的時(shí)候有沒(méi)有區(qū)分開(kāi)numpy.abs和abs函數(shù),別小看這兩個(gè)函數(shù),如果在寫(xiě)程序的時(shí)候正確區(qū)分使用這兩個(gè)函數(shù)可以使自己的程序運(yùn)行效率大大提升。
別看這兩個(gè)函數(shù)都能對(duì)整數(shù)求絕對(duì)值,但他們倆的返回值類型完全不一樣,如果傻傻地混為一談,將會(huì)使你的程序運(yùn)行時(shí)間被大大拖累!
今天筆者就帶小伙伴們看看,這兩個(gè)函數(shù)究竟該怎么正確使用才能使自己的程序運(yùn)行效率得到提升。
先看示例程序-abs()函數(shù)
注意觀察變量row和語(yǔ)句temp=row-1
import time row=-1000 row=abs(row) #這里的函數(shù)是abs() start_time = time.time()#記錄程序運(yùn)行到這(記為A)的時(shí)間 for i in range(row): for j in range(1000): temp=row-1 #temp在這里只是用來(lái)接收row-1的結(jié)果 end_time = time.time()#記錄程序運(yùn)行到這(記為B)的時(shí)間 print(end_time-start_time)#輸出A和B代碼間的程序運(yùn)行時(shí)間
運(yùn)行時(shí)間為:0.08079314231872559
再看示例程序-numpy.abs()函數(shù)
注意觀察變量row和語(yǔ)句temp=row-1
import numpy import time row=-1000 row=numpy.abs(row) #這里的函數(shù)是numpy.abs() start_time = time.time()#記錄程序運(yùn)行到這(記為A)的時(shí)間 for i in range(row): for j in range(1000): temp=row-1 #temp在這里只是用來(lái)接收row-1的結(jié)果 end_time = time.time()#記錄程序運(yùn)行到這(記為B)的時(shí)間 print(end_time-start_time)#輸出A和B代碼間的程序運(yùn)行時(shí)間
運(yùn)行時(shí)間為:0.20246124267578125
觀察兩個(gè)程序的結(jié)果
觀察兩個(gè)程序的相同代碼段運(yùn)行時(shí)間的結(jié)果,你會(huì)發(fā)現(xiàn)作用都是用來(lái)取整的abs()函數(shù)和numpy.abs()函數(shù),運(yùn)行時(shí)間竟然差了大約2.5倍!
小伙伴們看到這里是不是十分驚訝和不解?為什么相同的代碼段運(yùn)行時(shí)間竟然大不相同?雖然在本文章中,它們的相同代碼段運(yùn)行時(shí)間只差了0點(diǎn)幾秒,但是在做數(shù)據(jù)處理時(shí),龐大的數(shù)據(jù)處理足足可以使這微小的差距瞬間拉大,造成本來(lái)可以幾秒鐘運(yùn)行結(jié)束的程序你卻用了幾分鐘跑完的尷尬局面。
分析解釋
注意觀察兩個(gè)程序的變量row,
第一個(gè)程序
row=abs(row)
第二個(gè)程序
row=numpy.abs(row)
小伙伴們第一眼看好像這兩個(gè)函數(shù)除了外貌不同外,也沒(méi)啥不同,都是對(duì)變量row取絕對(duì)值,但是這兩個(gè)函數(shù)恰恰在返回值類型上不同。abs()函數(shù)返回的類型是int型而numpy.abs()函數(shù)返回的類型卻是ndarray。小伙伴們可以使用Type()函數(shù)來(lái)看變量row的類型,或者去numpy的官網(wǎng)看一下numpy.abs()函數(shù)的說(shuō)明,鏈接附上:numpy.abs()函數(shù)官方說(shuō)明
int類型這里不做過(guò)多解釋,有興趣的小伙伴可以自己去了解相關(guān)知識(shí)。
而ndarray類型,是numpy庫(kù)里的數(shù)組類型,它是numpy庫(kù)里的一種類(numpy.ndarray),小伙伴們可以去官網(wǎng)上看看有關(guān)ndarray類型的說(shuō)明。鏈接附上:numpy.ndarray類型官方說(shuō)明
有了上面的基礎(chǔ),我們?cè)賮?lái)理解為什么會(huì)出現(xiàn)相同代碼段運(yùn)行時(shí)間不同就變得容易許多了。其主要原因在于
temp=row-1
這段代碼。如果row變量是ndarray類型,那么ndarray類型減去int類型(常量1是int類型)就會(huì)存在不同類型間的變量進(jìn)行轉(zhuǎn)換的問(wèn)題(這種轉(zhuǎn)換是系統(tǒng)自己完成的,也可以稱之為隱藏式地轉(zhuǎn)換),這會(huì)使程序有額外的開(kāi)銷,使程序的運(yùn)行效率降低。而如果row變量是int類型就不會(huì)出現(xiàn)這種問(wèn)題,所以這就是使兩段相同的代碼運(yùn)行時(shí)間不同的根本原因所在。
另外numpy.abs()函數(shù)希望的參數(shù)類型是ndarray類型,而abs()函數(shù)希望的參數(shù)類型之一是int類型,所以numpy.abs(row)和abs(row)也存在上述問(wèn)題。
拓展
雖然numpy.abs()函數(shù)對(duì)單個(gè)元素(整型、浮點(diǎn)型等等)的處理較abs()函數(shù)慢,但如果元素很多,可以把這些元素組合起來(lái)形成一個(gè)ndarray類型數(shù)組,這時(shí)使用numpy.abs()函數(shù)(ndarray類型做實(shí)際參數(shù))就要比用abs()函數(shù)循環(huán)處理快得多啦。
補(bǔ)充:numpy abs()報(bào)錯(cuò)
我在用numpy的abs()給數(shù)組取絕對(duì)值的時(shí)候出現(xiàn)了這個(gè)問(wèn)題,很明顯是dtype的問(wèn)題
'<U32'是unsigned 32的含義,那么這個(gè)格式本來(lái)就沒(méi)有符號(hào),我還非要取絕對(duì)值那肯定會(huì)報(bào)錯(cuò)的呀!
回過(guò)頭去看了看果然是append進(jìn)數(shù)組的時(shí)候忘了把格式強(qiáng)轉(zhuǎn)成float了
OK!轉(zhuǎn)換!解決!
ufunc 'absolute' did not contain a loop with signature matching types dtype('<U32') dtype('<U32')
總結(jié)
單個(gè)元素用abs()函數(shù)
多個(gè)元素并行處理用numpy.abs()函數(shù)
使用函數(shù)和寫(xiě)代碼時(shí)一定要注意變量隱藏式地轉(zhuǎn)換,因?yàn)檫@能在無(wú)形之中拖慢你程序的運(yùn)行速度。
到此這篇關(guān)于Python中numpy.abs和abs函數(shù)的文章就介紹到這了,更多相關(guān)Python numpy.abs和abs函數(shù)內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Python用棧實(shí)現(xiàn)隊(duì)列的基本操作
隊(duì)列(Queue)和棧(Stack)是常見(jiàn)的數(shù)據(jù)結(jié)構(gòu),它們?cè)谟?jì)算機(jī)科學(xué)中有著廣泛的應(yīng)用,在Python中,可以使用列表(List)來(lái)實(shí)現(xiàn)棧,但要用棧來(lái)實(shí)現(xiàn)隊(duì)列需要一些巧妙的操作,本文就給大家詳細(xì)介紹一下Python中如何用棧實(shí)現(xiàn)隊(duì)列,需要的朋友可以參考下2023-11-11Python 圖形界面框架TkInter之在源碼中找pack方法
這篇文章主要介紹了Python 圖形界面框架TkInter之在源碼中找pack方法,根據(jù)不同的需求,選擇對(duì)應(yīng)的布局方式,每個(gè)控件都可以使用pack作為布局管理,下面我們就來(lái)看看從源碼中找pack()在哪里,需要的朋友可以參考下2022-03-03Python??處理?Pandas?DataFrame?中的行和列
這篇文章主要介紹了Python處理Pandas?DataFrame中的行和列,文章圍繞主題展開(kāi)詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下2022-09-09Python 樹(shù)表查找(二叉排序樹(shù)、平衡二叉樹(shù))
本文并不會(huì)深入講解樹(shù)數(shù)據(jù)結(jié)構(gòu)的基本的概念,僅是站在使用的角度說(shuō)清楚動(dòng)態(tài)查詢。閱讀此文之前,請(qǐng)預(yù)備一些樹(shù)的基礎(chǔ)知識(shí)。2023-01-01Python隨機(jī)生成信用卡卡號(hào)的實(shí)現(xiàn)方法
這篇文章主要介紹了Python隨機(jī)生成信用卡卡號(hào)的實(shí)現(xiàn)方法,可實(shí)現(xiàn)生成信用卡卡號(hào)的功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-05-05Python?lambda函數(shù)保姆級(jí)使用教程
本文和你一起探索Python中的lambda函數(shù),讓你以最短的時(shí)間明白這個(gè)函數(shù)的原理。也可以利用碎片化的時(shí)間鞏固這個(gè)函數(shù),讓你在處理工作過(guò)程中更高效2022-06-06Python實(shí)現(xiàn)暴力破解有密碼的zip文件的方法
這篇文章主要介紹了Python實(shí)現(xiàn)暴力破解有密碼的zip文件的方法,本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-03-03pandas實(shí)現(xiàn)to_sql將DataFrame保存到數(shù)據(jù)庫(kù)中
這篇文章主要介紹了pandas實(shí)現(xiàn)to_sql將DataFrame保存到數(shù)據(jù)庫(kù)中,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2019-07-07