2015-10-15 48 views
0

我已閱讀this blog,它顯示了算法如何使用numpy提高250倍速度。我曾嘗試使用numpy的改善以下代碼,但我不能讓它工作:如何使用numpy提高python代碼性能

for i in nodes[1:]: 
     for lb in range(2, diameter+1): 
      not_valid_colors = set() 
      valid_colors = set() 

      for j in nodes: 
       if j == i: 
        break 

       if distances[i-1, j-1] >= lb: 
        not_valid_colors.add(c[j, lb]) 
       else: 
        valid_colors.add(c[j, lb]) 

       c[i, lb] = choose_color(not_valid_colors, valid_colors) 

    return c 

說明

上面的代碼是用來計算自相似尺寸的算法的一部分一張圖。它基本上通過構建雙圖G'來工作,其中如果兩個圖之間的距離大於或等於給定值(Lb),則節點與其他節點相連,然後計算這些雙網上的圖着色。

該算法描述如下:

  1. 從1分配一個唯一的ID N到所有網絡節點,而不分配任何顏色愛好。
  2. 對於所有Lb的值,顏色值0分配給具有ID,IE C_1l
  3. 值= 1 = 0設置的ID I = 2。重複以下的節點,直到I = N.
    • a)計算從i到網絡中所有節點的距離l_ij,id j小於i。 c)從l_ij≥Lb的所有節點j < i中選擇一個未使用的顏色C [j] [l_ij]。這是給定Lb值的節點i的顏色C [i] [Lb]。
    • d)將Lb增加1並重復(c)直到Lb = Lb_max。
    • e)通過1

wrote it in python增加I,但它需要一分鐘以上時嘗試與具有100個節點和p = 0.9小型網絡中使用它。

因爲我還是新來的python和numpy,我沒有找到提高效率的方法。

是否可以通過使用numpy.where找到路徑比給定Lb更長的路徑來刪除循環?我試圖實現它,但沒有奏效...

+1

但是在SO上比在CR上有更多'numpy'知識豐富的海報。 CR對問題格式也很挑剔。 '矢量化'是SO'numpy'的共同話題。 – hpaulj

+2

'numpy'可以加速很多事情,如果你的問題在本質上是平行的 - 對一個元素做同樣的事情,不管順序如何。但如果問題是連續的 - 第i個元素的行爲取決於先前對'i-1'的行爲,那麼'numpy'通常不起作用。 – hpaulj

+0

同意@hpaulj詢問表現,在此處向量化相關問題。同樣對於OP來說,如果代替集合,列表或甚至更好的情況下使用numpy數組,當查看向量化代碼時會更容易。 – Divakar

回答

1

與numpy的數組矢量化操作快速,因爲實際的計算是這樣的底層庫完成作爲BLASLAPACK沒有Python開銷。使用循環密集型操作時,您不會看到這些好處。

您通常必須找出一種矢量化操作的方法(通常可以通過智能使用數組切片)。但是,有些操作本質上是循環密集型的,有時候對它們進行矢量化並不容易(對於您的代碼來說似乎就是這種情況)。

在這些情況下,您可以先嚐試Numba,它可以從Python函數生成優化的機器代碼而不做任何修改。 (你只需註解該功能,它會自動爲你做)。我沒有太多的經驗,並沒有嘗試過將它用於複雜的功能。

如果這不起作用,那麼你可以使用Cython,它會自動轉換類Python代碼(有類型的變量)爲有效的C代碼,並生成一個Python擴展模塊,它可以導入並在Python中使用。這通常會給你至少一個數量級(通常是兩個數量級)的加速循環密集型操作。我通常發現Cython易於使用,因爲與純C不同,可以直接在Cython代碼中訪問您的numpy數組。

我推薦使用Anaconda Python distribution,因爲您可以輕鬆安裝這些軟件包。對不起,我沒有針對您的代碼的特定答案。

+0

謝謝你的解釋和建議,我會嘗試這兩個選項,並讓你知道結果! – Hernandcb

+0

您不必使用'numpy'來使用'Cython'。實際上,它對於常規的Python列表操作可能更有效 - 請檢查其文檔。 – hpaulj

+0

我從來沒有說過你必須這樣做。 :) – joon

1

,如果你想去numpy的,你可以改變列表成陣列, 例如distances[i-1][j-1]成爲distances[i-1, j-1]後聲明的距離爲numpy的陣列。與c[i][lb]相同。關於valid_colorsnot_valid_colors你應該多想一點,因爲用numpy數組你不能附加東西:數組有固定長度,所以你應該在之前修復最大尺寸。另一個想法是,在你掌握了所有的東西之後,你可以將你的代碼編碼爲,這意味着你的所有循環將變得非常快。在任何情況下,如果你不想用Cython,你看博客,可以看到distances聲明爲在數組中main()