我想生成一個二維numpy陣列,其中的元素是從它們的位置計算出來的。類似于以下代碼:
import numpy as np
def calculate_element(i, j, other_parameters):
# do something
return value_at_i_j
def main():
arr = np.zeros((M, N)) # (M, N) is the shape of the array
for i in range(M):
for j in range(N):
arr[i][j] = calculate_element(i, j, ...)
這段代碼運行得非常慢,因為 Python 中的回圈效率不高。在這種情況下有什么方法可以更快地做到這一點?
順便說一句,現在我通過計算兩個二維“索引矩陣”來使用一種解決方法。像這樣的東西:
def main():
index_matrix_i = np.array([range(M)] * N).T
index_matrix_j = np.array([range(N)] * M)
'''
index_matrix_i is like
[[0,0,0,...],
[1,1,1,...],
[2,2,2,...],
...
]
index_matrix_j is like
[[0,1,2,...],
[0,1,2,...],
[0,1,2,...],
...
]
'''
arr = calculate_element(index_matrix_i, index_matrix_j, ...)
Edit1:應用“索引矩陣”技巧后代碼變得更快,所以我想問的主要問題是是否有辦法不使用這個技巧,因為它需要更多記憶體。簡而言之,我想要一個在時間和空間上都高效的解決方案。
Edit2:我測驗的一些示例
# a simple 2D Gaussian
def calculate_element(i, j, i_mid, j_mid, i_sig, j_sig):
gaus_i = np.exp(-((i - i_mid)**2) / (2 * i_sig**2))
gaus_j = np.exp(-((j - j_mid)**2) / (2 * j_sig**2))
return gaus_i * gaus_j
# size of M, N
M, N = 1200, 4000
# use for loops to go through every element
# this code takes ~10 seconds
def main_1():
arr = np.zeros((M, N)) # (M, N) is the shape of the array
for i in range(M):
for j in range(N):
arr[i][j] = calculate_element(i, j, 600, 2000, 300, 500)
# print(arr)
plt.figure(figsize=(8, 5))
plt.imshow(arr, aspect='auto', origin='lower')
plt.show()
# use index matrices
# this code takes <1 second
def main_2():
index_matrix_i = np.array([range(M)] * N).T
index_matrix_j = np.array([range(N)] * M)
arr = calculate_element(index_matrix_i, index_matrix_j, 600, 2000, 300, 500)
# print(arr)
plt.figure(figsize=(8, 5))
plt.imshow(arr, aspect='auto', origin='lower')
plt.show()
uj5u.com熱心網友回復:
您可以使用
并列numba
import numba as nb # tested with numba 0.55.1
@nb.njit(parallel=True)
def calculate_element_nb(i, j, i_mid, j_mid, i_sig, j_sig):
res = np.empty((i,j), np.float32)
for i in nb.prange(res.shape[0]):
for j in range(res.shape[1]):
res[i,j] = np.exp(-(i - i_mid)**2 / (2 * i_sig**2)) * np.exp(-(j - j_mid)**2 / (2 * j_sig**2))
return res
M, N = 1200, 4000
calculate_element_nb(M, N, 600, 2000, 300, 500)
# %timeit 10 loops, best of 5: 80.4 ms per loop
plt.figure(figsize=(8, 5))
plt.imshow(calculate_element_nb(M, N, 600, 2000, 300, 500), aspect='auto', origin='lower')
plt.show()

uj5u.com熱心網友回復:
您可以使用單個回圈來填充多維串列,在完成其所有元素后,它將被轉換為np.array如下所示:
import numpy as np
m, n = 5, 5
arr = []
for i in range(0, m*n, n):
arr.append(list(range(i, i n)))
print(np.array(arr))
輸出:
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]
[20 21 22 23 24]]
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/462199.html
上一篇:我將如何使用Python和numpy來識別陣列中何時有x個相同的相鄰值?
下一篇:Python逐元素乘法
