美好的一天, 对于我的研究,我在2维中创建了细胞自动生成。该程序已经运行但我仍然尝试优化它。下面的代码段总结了2D阵列中的中心单元的所有8个相邻单元。之后,下一个单元被定义为总和的函数。 有没有比2 for-loops更快的方法?
之前我甚至有4个for循环用于求和,但它比现在慢2倍......
n = len(mat1)
m = len(mat1[0])
mat2 = np.zeros((n,m))
sumN = 0
start = time.time()
for i in range(1,n-1):
for j in range(1,m-1):
sumN = mat1[i-1,j-1] + mat1[i-1,j] + mat1[i-1,j+1] + mat1[i,j-1] +mat1[i,j+1] + mat1[i+1,j] + mat1[i+1,j+1]+ mat1[i+1,j-1]
if str(sumN) in B and mat1[i,j] == 0:
mat2[i,j] = 1
elif str(sumN) in S and mat1[i,j] == 1:
mat2[i,j] = 1
sumN = 0
end = time.time()
print end - start
感谢xnx,我将滚动包含在矩阵上,而不是遍历所有元素。之后我创建了一个布尔2D numpy数组,用于初始化下一代。
sumN = sum(np.roll(np.roll(mat1, i, 0), j, 1)
for i in (-1, 0, 1) for j in (-1, 0, 1)
if (i != 0 or j != 0)).flatten()
mat1 = mat1.flatten()
b = np.array(map(lambda x,l: ((int(x) == 0) and (str(int(l)) in B))
or ((int(x) == 1) and (str(int(l)) in S)), mat1,sumN)).reshape(n,m)
mat2 = np.zeros((n,m))
mat2[b] = 1
mat2 = mat2.reshape(n,m)
答案 0 :(得分:1)
this blog article中提供了一种很好的方法:
nbrs_count = sum(np.roll(np.roll(mat1, i, 0), j, 1)
for i in (-1, 0, 1) for j in (-1, 0, 1)
if (i != 0 or j != 0))
这是有效的,因为numpy.roll(a, shift, axis)
沿给定的轴移动元素axis
,指定数量的地方shift
进行换行,因此可以依次访问每个8个单元格如果您遍历行i=-1,0,1
和列j=-1,0,1
,但请注意不要计算中心单元本身。
答案 1 :(得分:0)
不确定这是否更快(您应该使用您的数据集检查它),但您尝试做的似乎接近图像处理。
Scikit图像是一个非常好的模块,并且有很好的机会比你的解决方案快得多,因为很多功能都是在C / Fortran中实现的。
from skimage.morphology import square
import skimage.filters.rank as rank
import numpy as np
sumN=rank.sum(mat1,square(3)) # sum of each pixels in a 3 pixel-sided square
# compare with B and S :
n,m =np.shape(mat1)
sumN=np.flatten(sumN) # vectorize your array to be faster
mat1=np.flatten(sumN)
mat2=np.zeros_like(mat1)
for i in range(len(mat1): # only looping on 1 variable is faster
if str(sumN[i]) in B and mat1[i] == 0:
mat2[i] = 1
elif str(sumN[i]) in S and mat1[i] == 1:
mat2[i] = 1
mat1=mat1.reshape(n,m) # go back to the previous shape
mat2=mat2.reshape(n,m)