我可以矢量化此 Python 代码吗?
Can I vectorize this Python code?
我是 Python 的新手,我必须实现此代码的 "fast as possible" 版本。
s="<%dH" % (int(width*height),)
z=struct.unpack(s, contents)
heights = np.zeros((height,width))
for r in range(0,height):
for c in range(0,width):
elevation=z[((width)*r)+c]
if (elevation==65535 or elevation<0 or elevation>20000):
elevation=0.0
heights[r][c]=float(elevation)
我已经阅读了一些 python 矢量化问题...但我认为它不适用于我的情况。大多数问题都是使用 np.sum
而不是 for loops
。我想我有两个问题:
- 是否可以加快此代码的速度...我认为
heights[r][c]=float(elevation)
是瓶颈所在。我需要找到一些 Python 计时命令来确认这一点。
- 如果可以加快此代码。我有哪些选择?我看到有人推荐
cython
、pypy
、weave
。我可以在 C 中更快地完成此操作,但此代码还需要生成绘图,因此我想坚持使用 Python,以便我可以使用 matplotlib
。
正如您提到的,使用 numpy
编写快速代码的关键涉及向量化,并将工作推给快速的 C 级例程而不是 Python 循环。相对于您的原始代码,通常的方法似乎可以将事情改进十倍左右:
def faster(elevation, height, width):
heights = np.array(elevation, dtype=float)
heights = heights.reshape((height, width))
heights[(heights < 0) | (heights > 20000)] = 0
return heights
>>> h,w = 100, 101; z = list(range(h*w))
>>> %timeit orig(z,h,w)
100 loops, best of 3: 9.71 ms per loop
>>> %timeit faster(z,h,w)
1000 loops, best of 3: 641 µs per loop
>>> np.allclose(orig(z,h,w), faster(z,h,w))
True
这个比例似乎会持续更长时间 z
:
>>> h,w = 1000, 10001; z = list(range(h*w))
>>> %timeit orig(z,h,w)
1 loops, best of 3: 9.44 s per loop
>>> %timeit faster(z,h,w)
1 loops, best of 3: 675 ms per loop
我是 Python 的新手,我必须实现此代码的 "fast as possible" 版本。
s="<%dH" % (int(width*height),)
z=struct.unpack(s, contents)
heights = np.zeros((height,width))
for r in range(0,height):
for c in range(0,width):
elevation=z[((width)*r)+c]
if (elevation==65535 or elevation<0 or elevation>20000):
elevation=0.0
heights[r][c]=float(elevation)
我已经阅读了一些 python 矢量化问题...但我认为它不适用于我的情况。大多数问题都是使用 np.sum
而不是 for loops
。我想我有两个问题:
- 是否可以加快此代码的速度...我认为
heights[r][c]=float(elevation)
是瓶颈所在。我需要找到一些 Python 计时命令来确认这一点。 - 如果可以加快此代码。我有哪些选择?我看到有人推荐
cython
、pypy
、weave
。我可以在 C 中更快地完成此操作,但此代码还需要生成绘图,因此我想坚持使用 Python,以便我可以使用matplotlib
。
正如您提到的,使用 numpy
编写快速代码的关键涉及向量化,并将工作推给快速的 C 级例程而不是 Python 循环。相对于您的原始代码,通常的方法似乎可以将事情改进十倍左右:
def faster(elevation, height, width):
heights = np.array(elevation, dtype=float)
heights = heights.reshape((height, width))
heights[(heights < 0) | (heights > 20000)] = 0
return heights
>>> h,w = 100, 101; z = list(range(h*w))
>>> %timeit orig(z,h,w)
100 loops, best of 3: 9.71 ms per loop
>>> %timeit faster(z,h,w)
1000 loops, best of 3: 641 µs per loop
>>> np.allclose(orig(z,h,w), faster(z,h,w))
True
这个比例似乎会持续更长时间 z
:
>>> h,w = 1000, 10001; z = list(range(h*w))
>>> %timeit orig(z,h,w)
1 loops, best of 3: 9.44 s per loop
>>> %timeit faster(z,h,w)
1 loops, best of 3: 675 ms per loop