下面的代码检查python中对象像素的周围像素。
self.surr = [None, None, None, None, None, None, None, None]
for i in range(9):
#for x in range(-1, 2):
#for y in range(-1, 2):
if i != 5:
x = i % 3 - 2
y = int((i % 3) / 3) - 1
if x == 0 and y == 0:
pass
else:
PAI = allPixels[(self.x + x) % width][(self.y + y) % height] if allPixels[(self.x + x) % width][(self.y + y) % height] != None else None
self.surr[(y * 3) + x] = (PAI)
return self.surr
这将返回一个长度为8的列表,其中包含Pixel
个对象或None
。 allPixels是一个2D数组,它同时保存Pixel
个对象或None
。
我已经尝试了那些被注释掉的嵌套循环,但它们运行的速度比我目前正在使用的方法慢一点。然而,这仍然太慢,就像屏幕上有3000个像素一样,这是屏幕最后会出现的总像素的下限,做数学运算并且每帧都有很多。< / p>
如何使用NumPy或其他方法更快地运行?
如果您想查看整个代码,可以在此处找到:https://pastebin.com/EuutUVjS
感谢你们给我的任何帮助!
答案 0 :(得分:3)
你所做的事情本来就需要循环 - 但是如果你可以将循环变成numpy,那么它通常会快5-20倍。
在您的情况下,您尝试做的是将每个像素与其邻居进行比较。你怎么能这样做作为一个阵列范围的操作?简单:将数组与相移的数组进行比较。
这是一个更简单的例子:
>>> a = np.array([1,2,4,8,16])
>>> for i in range(1, len(a)):
... print(a[i] - a[i-1], end=' ')
1 2 4 8
>>> print(a[1:] - a[:-1])
[1 2 4 8]
因此,对于2D阵列,它只是:
north = a[:-1]
ne = a[:-1,1:]
east = a[:,1:]
se = a[1:,1:]
south = a[1:]
sw = a[1:,:-1]
west = a[:,:-1]
nw = a[:-1,:-1]
请注意,这并不会浪费大量时间或内存来构建8个额外的阵列;它只是在同一个内存上创建了8个视图。
有关使用这些移位数组进行Conway Game of Life模拟的示例,请参阅this answer on compsci。
如果你想以不同的方式处理边界,你可能需要&#34;零延伸&#34;数组,但这是你可能遇到的唯一复杂性。
但是,如果您在其中存储Python对象,那么您可以从numpy中获得多少好处。通常,您希望存储数字数组。
我不知道你Pixel
个对象中的内容,但是让我们假设它们只是颜色值,就像三个花车一样。在这种情况下,您可以使用具有三个浮点数的结构化dtype的2D数组,或者只使用三维数组(按r-g-b逐列),使用NaN值代替None
。
如果这样做,阵列范围的操作可以以接近机器本机的速度运行,包括使用SIMD操作实现数据并行。如果你不这样做,只有循环以原生速度发生;循环中的算法仍然和非Numpy Python一样慢。
答案 1 :(得分:-1)