在python中,有没有什么方法可以用更有效的方法来替换for循环

2024-10-01 07:28:05 发布

您现在位置:Python中文网/ 问答频道 /正文

下面的代码检查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个像素,这是最后屏幕上总像素的下限,算了算,每一帧都有很多内容。在

我怎样才能让这个运行更快,也许使用NumPy或其他方法?在

如果您想查看整个代码,可以在这里找到:https://pastebin.com/EuutUVjS

谢谢你能给我的任何帮助!在


Tags: 对象代码inselfnoneforifrange
1条回答
网友
1楼 · 发布于 2024-10-01 07:28:05

你所做的事情本身就需要循环,但是如果你能把循环变成numpy,它通常会快5-20倍。在

在您的例子中,您要做的是将每个像素与其相邻像素进行比较。如何在整个阵列范围内执行此操作?简单:将数组与移位1的同一数组进行比较。在

下面是一个简单的例子:

>>> 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]

因此,对于二维阵列,它只是:

^{pr2}$

请注意,这并不是浪费大量的时间或内存来构建8个额外的数组;它只是在同一个内存上创建8个视图。在

请参见this answer on compsci以获取将这些移位数组用于康威人生游戏模拟的示例。在

如果您想以不同的方式处理边界,您可能需要“零扩展”数组,但这是您可能遇到的唯一复杂性。在


但是,如果在numpy中存储Python对象,那么从numpy中获得的好处是有限的。通常,您希望存储数字数组。在

我不知道你的Pixel对象中有什么,但让我们假设它们只是颜色值,就像三个浮点数。在这种情况下,您可以使用一个具有三个float的结构化数据类型的2D数组,或者仅仅使用一个3D数组(按r-g-b逐行),任何一种方式都可以使用NaN值来代替None。在

如果这样做,阵列范围内的操作可以以接近机器的本机速度运行,包括使用SIMD操作实现数据并行。如果不这样做,则只有循环以本机速度进行;循环中的算术仍然与非numpython中一样慢。在

相关问题 更多 >