實例詳解Python中的numpy.abs和abs函數

說在最前

不知道小夥伴們在寫代碼的時候有沒有區分開numpy.abs和abs函數,別小看這兩個函數,如果在寫程序的時候正確區分使用這兩個函數可以使自己的程序運行效率大大提升。

別看這兩個函數都能對整數求絕對值,但他們倆的返回值類型完全不一樣,如果傻傻地混為一談,將會使你的程序運行時間被大大拖累!

今天筆者就帶小夥伴們看看,這兩個函數究竟該怎麼正確使用才能使自己的程序運行效率得到提升。

先看示例程序-abs()函數

註意觀察變量row和語句temp=row-1

import time

row=-1000
row=abs(row)  #這裡的函數是abs()

start_time = time.time()#記錄程序運行到這(記為A)的時間

for i in range(row):
    for j in range(1000):
        temp=row-1    #temp在這裡隻是用來接收row-1的結果

end_time = time.time()#記錄程序運行到這(記為B)的時間
print(end_time-start_time)#輸出A和B代碼間的程序運行時間

運行時間為:0.08079314231872559

再看示例程序-numpy.abs()函數

註意觀察變量row和語句temp=row-1

import numpy
import time

row=-1000
row=numpy.abs(row)   #這裡的函數是numpy.abs()

start_time = time.time()#記錄程序運行到這(記為A)的時間

for i in range(row):
    for j in range(1000):
        temp=row-1    #temp在這裡隻是用來接收row-1的結果

end_time = time.time()#記錄程序運行到這(記為B)的時間
print(end_time-start_time)#輸出A和B代碼間的程序運行時間

運行時間為:0.20246124267578125

觀察兩個程序的結果

觀察兩個程序的相同代碼段運行時間的結果,你會發現作用都是用來取整的abs()函數和numpy.abs()函數,運行時間竟然差瞭大約2.5倍!

小夥伴們看到這裡是不是十分驚訝和不解?為什麼相同的代碼段運行時間竟然大不相同?雖然在本文章中,它們的相同代碼段運行時間隻差瞭0點幾秒,但是在做數據處理時,龐大的數據處理足足可以使這微小的差距瞬間拉大,造成本來可以幾秒鐘運行結束的程序你卻用瞭幾分鐘跑完的尷尬局面。

分析解釋

註意觀察兩個程序的變量row,

第一個程序

row=abs(row)

第二個程序

row=numpy.abs(row)

小夥伴們第一眼看好像這兩個函數除瞭外貌不同外,也沒啥不同,都是對變量row取絕對值,但是這兩個函數恰恰在返回值類型上不同。abs()函數返回的類型是int型而numpy.abs()函數返回的類型卻是ndarray。小夥伴們可以使用Type()函數來看變量row的類型,或者去numpy的官網看一下numpy.abs()函數的說明,鏈接附上:numpy.abs()函數官方說明

int類型這裡不做過多解釋,有興趣的小夥伴可以自己去瞭解相關知識。

而ndarray類型,是numpy庫裡的數組類型,它是numpy庫裡的一種類(numpy.ndarray),小夥伴們可以去官網上看看有關ndarray類型的說明。鏈接附上:numpy.ndarray類型官方說明

有瞭上面的基礎,我們再來理解為什麼會出現相同代碼段運行時間不同就變得容易許多瞭。其主要原因在於

temp=row-1

這段代碼。如果row變量是ndarray類型,那麼ndarray類型減去int類型(常量1是int類型)就會存在不同類型間的變量進行轉換的問題(這種轉換是系統自己完成的,也可以稱之為隱藏式地轉換),這會使程序有額外的開銷,使程序的運行效率降低。而如果row變量是int類型就不會出現這種問題,所以這就是使兩段相同的代碼運行時間不同的根本原因所在。

另外numpy.abs()函數希望的參數類型是ndarray類型,而abs()函數希望的參數類型之一是int類型,所以numpy.abs(row)和abs(row)也存在上述問題。

拓展

雖然numpy.abs()函數對單個元素(整型、浮點型等等)的處理較abs()函數慢,但如果元素很多,可以把這些元素組合起來形成一個ndarray類型數組,這時使用numpy.abs()函數(ndarray類型做實際參數)就要比用abs()函數循環處理快得多啦。

補充:numpy abs()報錯

我在用numpy的abs()給數組取絕對值的時候出現瞭這個問題,很明顯是dtype的問題

'<U32'是unsigned 32的含義,那麼這個格式本來就沒有符號,我還非要取絕對值那肯定會報錯的呀!

回過頭去看瞭看果然是append進數組的時候忘瞭把格式強轉成float瞭

OK!轉換!解決!

ufunc 'absolute' did not contain a loop with signature matching types dtype('<U32') dtype('<U32')

總結

單個元素用abs()函數

多個元素並行處理用numpy.abs()函數

使用函數和寫代碼時一定要註意變量隱藏式地轉換,因為這能在無形之中拖慢你程序的運行速度。

到此這篇關於Python中numpy.abs和abs函數的文章就介紹到這瞭,更多相關Python numpy.abs和abs函數內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: