python - 有没有办法用Python中更有效的东西替换for循环

标签 python performance numpy pygame

下面的代码检查 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

感谢您给我的任何帮助!

最佳答案

您正在做的事情本质上需要循环 - 但如果您可以将该循环移动到 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]

因此,对于二维数组,它只是:

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 个 View 。

参见this answer on compsci有关使用这些移位数组进行康威生命游戏模拟的示例。

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


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

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

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

关于python - 有没有办法用Python中更有效的东西替换for循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50438206/

相关文章:

mysql - 帮助加速此 MySQL 查询,该查询由于聚合函数而花费的时间过长

python - python数组的高效移动、稳健尺度估计

python - 如何根据一列的值将numpy数组拆分为子数组

python - Boto 请求过期

multithreading - 多线程环境中的Malloc性能

python - 如何打印 ""内的变量?

c - 在 C 中检查全零缓冲区的更快方法?

python - 使用 numpy/scipy 计算矩阵中每个单元格的邻域积

Python字符串分割顺序错误

python - Seaborn pairplot 和 NaN 值