我有四個 (nx1) 維陣列,名為 a、b、c 和 F。我想在沒有任何回圈的情況下運行此演算法。
for i in range(n):
if a[i] < b[i]:
F[i] = 0
elif a[i] > c[i]:
F[i] = 1
elif b[i] <= a[i] <= c[i]:
F[i] = 2
我想以更矢量化的方式撰寫此代碼,以使其更高效,因為我的資料集非常大。
uj5u.com熱心網友回復:
我覺得你可以為這個任務使用布爾索引。
F[np.logical_and(b <= a, a <= c)] = 2
F[a > c] = 1
F[a < b] = 0
請注意,為了獲得預期的結果,矯揉造作的順序在這里很重要。
一些timeit
基準:
def loop(F, a, b, c):
for i in range(F.shape[0]):
if a[i] < b[i]:
F[i] = 0
elif a[i] > c[i]:
F[i] = 1
elif b[i] <= a[i] <= c[i]:
F[i] = 2
def idx(F, a, b, c):
F[np.logical_and(b <= a, a <= c)] = 2
F[a > c] = 1
F[a < b] = 0
使用(10x1)陣列:
>>> timeit.timeit(lambda: loop(F, a, b, c))
11.585818066001593
>>> timeit.timeit(lambda: idx(F, a, b, c))
3.337863392000145
使用(1000x1)陣列:
>>> timeit.timeit(lambda: loop(F, a, b, c))
1457.268110728999
>>> timeit.timeit(lambda: idx(F, a, b, c))
10.00236530300026
uj5u.com熱心網友回復:
如果你關心性能,為什么不試試numba
呢?它可能10X
比邏輯操作更快,同時節省記憶體。作為獎勵,您撰寫的回圈代碼將保持完整,僅通過@njit
函式前面的裝飾器。
from numba import njit
@njit
def loop(F, a, b, c):
for i in range(F.shape[0]):
if a[i] < b[i]:
F[i] = 0
elif a[i] < c[i]:
F[i] = 1
elif b[i] <= a[i] <= c[i]:
F[i] = 2
與@NiziL 使用大小為 100 和 1000 個向量的向量化解決方案進行比較,
timeit(lambda: loop(F, a, b, c))
timeit(lambda: idx(F, a, b, c))
給出:
# 1.0355658 (Size: 100, @njit loop)
# 4.6863165 (Size: 100, idx)
# 1.9563843 (Size: 1000, @njit loop)
# 16.658198 (Size: 1000, idx)
轉載請註明出處,本文鏈接:https://www.uj5u.com/shujuku/473539.html
上一篇:如何找到可能的組合