2016-09-21 85 views
1

我對Python非常陌生,我試圖習慣於執行Python的數組操作,而不是在數組中循環。下面是那種環接動作我做的一個例子,但我無法制定出不依賴於循環合適的純數組操作:使用多個相同數組索引的數組操作

import numpy as np 

def f(arg1, arg2): 
    # an arbitrary function 


def myFunction(a1DNumpyArray): 
    A = a1DNumpyArray  

    # Create a square array with each dimension the size of the argument array. 
    B = np.zeros((A.size, A.size)) 

    # Function f is a function of two elements of the 1D array. For each 
    # element, i, I want to perform the function on it and every element 
    # before it, and store the result in the square array, multiplied by 
    # the difference between the ith and (i-1)th element. 
    for i in range(A.size): 
    B[i,:i] = f(A[i], A[:i])*(A[i]-A[i-1]) 

    # Sum through j and return full sums as 1D array. 
    return np.sum(B, axis=0) 

總之,我整合功能,有兩個相同數組的元素作爲參數,返回積分結果數組。

有沒有更緊湊的方式來做到這一點,而不使用循環?

+0

現在閱讀起來比較容易。任何你想妥協的理由? – erip

+0

我被一位資深Pythoneer告知:「不要使用循環來操作數組,使用數組操作。」顯然,如果這太過於妥協易讀性,我會堅持循環。 –

+1

我想說一個更好的規則是「不要使用循環來操作數組,如果存在一個數組操作來執行你所需要的操作」。 – Kevin

回答

0

使用任意f函數,而這個[i, :i]業務通過傳遞循環而變得複雜。

大部分快速編譯的numpy操作對整個數組或整行和/或列起作用,並且可以有效地並行執行。循環固有的循環(來自一個循環的值取決於前一個循環)不適合。每個循環中不同大小的列表或數組也是一個很好的指示器,「矢量化」將很困難。

for i in range(A.size): 
    B[i,:i] = f(A[i], A[:i])*(A[i]-A[i-1]) 

與樣品A和已知f(那樣簡單arg1*arg2),我會產生B陣列,並尋找治療B作爲一個整體的圖案。乍一看,它看起來像你的B是一個較低的三角形。有些功能可以幫助索引這些內容。但是最後的總和可能會改變這幅畫。

有時我會用自下而上的方法解決這些問題,首先嚐試去除內部循環。但在這種情況下,我認爲需要採取某種全方位的方法。