我可以将这个python代码向量化吗? [英] Can I vectorise this python code?
问题描述
我已编写此python代码来获取标签的邻居(一组共享某些公共属性的像素).标签的邻居定义为位于边界另一侧的其他标签(相邻标签共享边界).因此,我编写的代码可以运行,但是速度非常慢:
I have written this python code to get neighbours of a label (a set of pixels sharing some common properties). The neighbours for a label are defined as the other labels that lie on the other side of the boundary (the neighbouring labels share a boundary). So, the code I wrote works but is extremely slow:
# segments: It is a 2-dimensional numpy array (an image really)
# where segments[x, y] = label_index. So each entry defines the
# label associated with a pixel.
# i: The label whose neighbours we want.
def get_boundaries(segments, i):
neighbors = []
for y in range(1, segments.shape[1]):
for x in range(1, segments.shape[0]):
# Check if current index has the label we want
if segments[x-1, y] == i:
# Check if neighbour in the x direction has
# a different label
if segments[x-1, y] != segments[x, y]:
neighbors.append(segments[x,y])
# Check if neighbour in the y direction has
# a different label
if segments[x, y-1] == i:
if segments[x, y-1] != segments[x, y]:
neighbors.append(segments[x, y])
return np.unique(np.asarray(neighbors))
您可以想象,我可能在这里完全滥用了python.我想知道是否有一种方法可以优化此代码,使其更具pythonic性.
As you can imagine, I have probably completely misused python here. I was wondering if there is a way to optimize this code to make it more pythonic.
推荐答案
在这里:
def get_boundaries2(segments, i):
x, y = np.where(segments == i) # where i is
right = x + 1
rightMask = right < segments.shape[0] # keep in bounds
down = y + 1
downMask = down < segments.shape[1]
rightNeighbors = segments[right[rightMask], y[rightMask]]
downNeighbors = segments[x[downMask], down[downMask]]
neighbors = np.union1d(rightNeighbors, downNeighbors)
return neighbors
如您所见,根本没有Python循环.我还尝试最小化副本(第一次尝试制作segments
带有NAN边框的副本,但后来我设计了保持边界"检查).
As you can see, there are no Python loops at all; I also tried to minimize copies (the first attempt made a copy of segments
with a NAN border, but then I devised the "keep in bounds" check).
请注意,我没有从这里的邻居"中过滤出i
本身.您可以根据需要在末尾轻松添加.一些时间:
Note that I did not filter out i
itself from the "neighbors" here; you can add that easily at the end if you want. Some timings:
输入2000x3000:原始耗时13秒,我的耗时370毫秒(加速35倍).
Input 2000x3000: original takes 13 seconds, mine takes 370 milliseconds (35x speedup).
输入1000x300:原始耗时643毫秒,我的耗时17.5毫秒(36倍加速).
Input 1000x300: original takes 643 ms, mine takes 17.5 ms (36x speedup).
这篇关于我可以将这个python代码向量化吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!