我只是重新審視我的一些代碼,以提高性能和stumpled了一些奇怪的事情:包裝np.arrays __pow__方法
a = np.linspace(10,1000,1000000).reshape(1000,1000)
%timeit np.square(a)
100 loops, best of 3: 8.07 ms per loop
%timeit a*a
100 loops, best of 3: 8.18 ms per loop
%timeit a**2
100 loops, best of 3: 8.32 ms per loop
好它似乎有使用電運營商時,一些開銷(**
)但除此之外,他們似乎是相同的(我猜NumPy的是這樣做),但是它得到了奇怪:
In [46]: %timeit np.power(a, 2)
10 loops, best of 3: 121 ms per loop
所以沒有問題,但它似乎有點不一致有神奇的戰俘回退,但不是爲UFUNC 。但後來我有了興趣,因爲我使用的第三大國了很多:
%timeit a*a*a
100 loops, best of 3: 18.1 ms per loop
%timeit a**3
10 loops, best of 3: 121 ms per loop
%timeit np.power(a, 3)
10 loops, best of 3: 121 ms per loop
似乎是在第三功率和UFUNC和「magic-POW」沒有「捷徑」的工作方式相同(對於至少性能)。
但是這不是很好,因爲我想要一個在我的代碼中使用權力的一致方法,我不太確定如何包裝numpy的__pow__
。
所以去的地步,我的問題是:
有沒有一種方法,我可以包裝numpys __pow__
方法?因爲我想要在我的腳本中編寫權力的一致方式不寫a**2
和另一個地方power(a, 3)
。簡單地寫a**3
,並重定向到我的電源功能,將是首選(但爲此,我需要以某種方式包裝ndarrays __pow__
或?)。 目前我使用的快捷方式,但是這不是那個漂亮(我甚至不得不宣佈指數== 2的情況下,因爲np.power
執行不是最優的存在):
def power(array, exponent):
if exponent == 2: #catch this, or it calls the slow np.power(array, exponent)
return np.square(array)
if exponent == 3:
return array * array * array
#As soon as np.cbrt is avaiable catch the exponent 4/3 here too
return np.power(array, exponent)
%timeit power(a, 3)
100 loops, best of 3: 17.8 ms per loop
%timeit a**3
10 loops, best of 3: 121 ms per loop
我使用NumPy的v1.9.3,我不只是爲了包裝__pow__
方法而子類np.ndarray
。 :-)
編輯:我重寫了我得到我的問題的部分。澄清一下:我不是在問爲什麼NumPy會這樣做 - 這只是爲了解釋爲什麼我會問這個問題。
你真的想微方案優化電源操作員,因爲它快一點?這似乎真的被過度優化,特別是如果它意味着引入其他功能。只要一直使用'** n',並且不用擔心那麼小的時間差異 – poke
np.all(a ** 3 - a \ * a \ * a < 1e-6) ->是的,所以我認爲它是一樣的,對於你的numpy必須聲明它是一個矩陣來觸發矩陣乘法,是的問題是如何包裝\\ __ pow__。時間差異對我來說很重要,因爲我處理了很多真正的大數組(1000 1000×2000圖像)。對於編輯,我很新,沒有正確的文本格式 – MSeifert
不可能修改ndarray的'__pow__'方法而不使用子類。您可以(如您所建議的)編寫另一個函數。如果你關心性能,你可以使用像[numexpr](https://github.com/pydata/numexpr)這樣的庫,它具有優化的功能函數。例如,'numexpr.evaluate(「a ** 3 「)'比」a * a * a「大約快20倍。 –