簡體   English   中英

將關心索引的函數應用於numpy數組的每個元素

[英]Applying function that cares about index to every element of numpy array

我有一個三維numpy數組A.我想將每個元素A [i,j,k]乘以w *(i / Lx + j / Ly + k / Lz)其中w,Lx,Ly和Lz是實數(浮點數)。 在for循環中執行此操作是非常不切實際的,因為我需要能夠為大型數組縮放此值,並且在O(N ^ 3)中的三個索引ijk縮放上進行for循環。

有沒有一種有效的方法對關注索引的numpy數組的每個元素執行操作?

你可以使用broadcasting -

M,N,R = A.shape

p1 = np.arange(M)[:,None,None]/Lx
p2 = np.arange(N)[:,None]/Ly
p3 = np.arange(R)/Lz

out = A/(w*(p1 + p2 + p3))

您還可以使用np.ix_獲得更優雅的解決方案 -

M,N,R = A.shape
X,Y,Z = np.ix_(np.arange(M),np.arange(N),np.arange(R))
out = A/(w*((X/Lx) + (Y/Ly) + (Z/Lz)))

運行時測試和輸出驗證 -

功能定義:

def vectorized_app1(A, w, Lx, Ly, Lz ):
    M,N,R = A.shape
    p1 = np.arange(M)[:,None,None]/Lx
    p2 = np.arange(N)[:,None]/Ly
    p3 = np.arange(R)/Lz
    return A/(w*(p1 + p2 + p3))

def vectorized_app2(A, w, Lx, Ly, Lz ):
    M,N,R = A.shape
    X,Y,Z = np.ix_(np.arange(M),np.arange(N),np.arange(R))
    return A/(w*((X/Lx) + (Y/Ly) + (Z/Lz)))

def original_app(A, w, Lx, Ly, Lz ):
    out = np.empty_like(A)
    M,N,R = A.shape
    for i in range(M):
        for j in range(N):
            for k in range(R):
                out[i,j,k] = A[i,j,k]/(w*( (i / Lx) + (j / Ly) + (k / Lz) ))
    return out

時序:

In [197]: # Inputs
     ...: A = np.random.rand(100,100,100)
     ...: w, Lx, Ly, Lz = 2.3, 3.2, 4.2, 5.2
     ...: 

In [198]: np.allclose(original_app(A,w,Lx,Ly,Lz),vectorized_app1(A,w,Lx,Ly,Lz))
Out[198]: True

In [199]: np.allclose(original_app(A,w,Lx,Ly,Lz),vectorized_app2(A,w,Lx,Ly,Lz))
Out[199]: True

In [200]: %timeit original_app(A, w, Lx, Ly, Lz )
1 loops, best of 3: 1.39 s per loop

In [201]: %timeit vectorized_app1(A, w, Lx, Ly, Lz )
10 loops, best of 3: 24.6 ms per loop

In [202]: %timeit vectorized_app2(A, w, Lx, Ly, Lz )
10 loops, best of 3: 24.2 ms per loop

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM