2017-02-23 49 views
0

如果相同的子表達式出現在一個表達式中的多個地方,它是否會重新計算多次(或者是否足夠聰明以檢測這個並重新使用結果)?numexpr:臨時變量或重複的子表達式?

有什麼辦法可以在一個numexpr表達式中聲明臨時變量嗎?這將有兩個目的:

  1. 鼓勵numexpr考慮高速緩存和重新使用,而不是重新計算結果;
  2. 簡化表達式(使源代碼更易於閱讀和維護)。

我試圖計算F(G(X))其中˚F本身既複雜的表達式(例如,用於基於像素的主題分類,˚F是嵌套決策樹涉及多個閾值,g是一組歸一化差值比,並且x是多波段柵格圖像)。

回答

0

是的,如果一個子表達式在一個numexpr表達式中重複,那麼它將不會被重新計算。

這可以通過用numexpr.disassemble(numexpr.NumExpr(expr))代替numexpr.evaluate(expr)來驗證。

例如,表達"where(x**2 > 0.5, 0, x**2 + 10)"被編譯成這樣的:

y = x*x 
t = y>0.5 
y = y+10 
y[t] = 0 

(注乘法只出現一次,而不是兩次。)

出於這個原因,它是最好的,如果整個計算可以作爲一個單一的數字表達式輸入。避免在python中執行子計算(將中間結果或臨時變量分配到numpy數組中),因爲這隻會增加內存使用量並且會破壞numexpr的優化/加速(這涉及在CPU高速緩存大小的塊中執行此全部計算序列以逃避內存延遲)。

儘管如此,更可讀的代碼可以通過使用字符串替換被格式化:

f = """where({g} > 0.5, 
      0, 
      {g} + 10)""" 
g = "x**2" 
expr = f.format(g=g)