Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/300.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
加速python代码_Python_Matlab_Numpy - Fatal编程技术网

加速python代码

加速python代码,python,matlab,numpy,Python,Matlab,Numpy,编辑2:基于评论的其他信息: 该函数用于计算图像的径向积分(即极坐标),然后通过半径进行规格化。也就是说,在数学记数法中:rotmean=积分[f[r]r,{r,0,rmax}]/积分[r,{r,0,rmax}]。实际上,当我将图像从二维像素贴图展平到一维径向平均值时,我想进行双线性插值。如果我不插值,只使用最近邻,接近零半径的值可能会非常偏离 因此,该算法可以描述如下: 计算网格半径 找到半径的底面作为矩阵索引 为像素的双线性插值找到地板上的剩余部分 现在,对于底部给出的矢量化解决方案,我

编辑2:基于评论的其他信息: 该函数用于计算图像的径向积分(即极坐标),然后通过半径进行规格化。也就是说,在数学记数法中:rotmean=积分[f[r]r,{r,0,rmax}]/积分[r,{r,0,rmax}]。实际上,当我将图像从二维像素贴图展平到一维径向平均值时,我想进行双线性插值。如果我不插值,只使用最近邻,接近零半径的值可能会非常偏离

因此,该算法可以描述如下:

  • 计算网格半径

  • 找到半径的底面作为矩阵索引

  • 为像素的双线性插值找到地板上的剩余部分

现在,对于底部给出的矢量化解决方案,我进行了一些预计算:

  • 求由双线性插值(0和+1像素分别为mage_p和mage_n)加权的图像。这给出了径向和(而不是平均)积分[f[r]r,{r,0,rmax}]

  • 概念上(对我来说)将问题矢量化的困难步骤是将N**2像素图像压缩成N*sqrt(2)径向和。这是通过“rmean[rfloor]=mage_p”这样的行完成的,注意到rfloor都是长度N**2,而rmean是长度N*sqrt(2)

  • 还要计算权重,它给出积分[r,{r,0,rmax}]

  • 将径向和转换为平均值

原职: 我正在尝试将一个函数从Matlab移植到Python(基于WinPython x64 2.7.6.4)我正在努力解决它的速度有多慢。该代码旨在获取图像围绕中心的旋转平均值。通常,该应用程序将查找图像功率谱的旋转平均值,但它也可以用于图像空间。以下是代码:

def rotmean( mage ):
# This is terrifyingly slow
t0 = time.time()

N = int( np.floor( mage.shape[0]/2.0 ) )
M = int( np.floor( mage.shape[1]/2.0 ) )

rmax = np.ceil( np.sqrt( N**2 + M**2 ) ) + 1

rmean = np.zeros( [rmax] )
weights = np.zeros( [rmax] )

[xmesh, ymesh] = np.meshgrid( range(-N, N), range(-M, M) )
rmesh = np.sqrt( xmesh**2 + ymesh**2 )
rfloor = np.floor( rmesh )

remain = rmesh - rfloor
# Make rfloor into an index look-up table
rfloor = rfloor.astype(np.int)

t1 = time.time()
# It takes 300 ms just to get to here in the function.  
print "Init time = " + str(t1-t0)
print "Max rfloor = " + str( rfloor.max() )
print "rmean.shape = " + str( rmean.shape )


# Certainly mage*(1-remain) can be precalculated as well if we want to use more memory

for I in rfloor:
    # Sum pixels
    rmean[rfloor[I]] += mage[I]*(1-remain[I])
    rmean[rfloor[I]+1] += mage[I]*remain[I]

    # Calculate the total area of each pixel so we can compute the average from the sum
    weights[rfloor[I]] += (1-remain[I])
    weights[rfloor[I]+1] += remain[I]

t4 = time.time()
print "Total loop time = " + str(t4 - t1)

rmean /= weights # compute average from sum
raxis = range(0,rmean.size)
return [rmean, raxis]
与Matlab相比,很难理解该函数的速度有多慢。在我的笔记本电脑上执行Matlab大约需要450毫秒,而Python只需要300毫秒就可以到达for循环,在我功能更强大的桌面上执行2k x 2k图像大约需要180秒。我意识到Matlab使用JIT来编译for循环,但我尝试了编译将代码导入Cython以加速for循环,实际上它比解释的代码慢。我怀疑我不了解Python如何分配内存之类的内容,但我找不到任何有关分析的注意事项。从可用的有限文档中可以看出,我是在线(就地)完成的这里使用+=运算符进行操作

通过numpy进行矢量化似乎是一个显而易见的解决方案,但我不知道如何对操作进行矢量化

编辑:好的,我对代码进行了矢量化,现在距离很近,用Python大约0.5秒(尽管桌面计算机的CPU比i5强大得多,Xeon)。我尝试了许多方法来提高for循环的速度,但我能做的最好的事情是超过30秒

t0 = time.time()

N = int( np.floor( mage.shape[0]/2.0 ) )
M = int( np.floor( mage.shape[1]/2.0 ) )

rmax = np.ceil( np.sqrt( N**2 + M**2 ) ) + 1

[xmesh, ymesh] = np.meshgrid( range(-N, N), range(-M, M) )
rmesh = np.sqrt( xmesh**2 + ymesh**2 )
rfloor = np.floor( rmesh )

remain = rmesh - rfloor
# Make rfloor into an index look-up table
rfloor = rfloor.astype(np.int)

# I can flatten remain and mage
mage = mage.ravel()
remain = remain.ravel()
# remain_n = np.ones( remain.shape ) - remain;
remain_n = 1.0 - remain;
rfloor = rfloor.ravel()
mage_p = mage*remain
mage_n = mage*remain_n

# Somewhat better initialization time (~200 ms) but still slow...
t2 = time.time()
print "Initialize time = " + str(t2-t0)

rmean = np.zeros( [rmax] )
rmean_n = np.zeros( [rmax] )
weights = np.zeros( [rmax] )
weights_n = np.zeros( [rmax] )

# Find positive remainders
rmean[rfloor] = mage_p
weights[rfloor] = remain

# Add one to indexing array and add negative remainders to sum
rfloor += 1
rmean_n[rfloor] += mage_n
weights_n[rfloor] += remain_n

# sum
rmean += rmean_n
weights += weights_n
# and normalize sum to average
rmean /= weights

raxis = range(0,rmean.size)
t1 = time.time()
print "Time elapsed = " + str(t1-t0)

你能编辑你的问题来解释你的算法吗?我这里有一个简单的函数,可以生成这样一个径向轮廓,它也足够快(你的函数是11毫秒对28秒)如果你能解释算法,也许我会理解你在做什么。考虑在问题中包含你的Matlab代码,这样就更容易看到不同的东西了。我给这个问题增加了一个附加的编辑。我发现原来的(慢)。代码也有漏洞。我还没有正确测试快速矢量化解决方案(针对分析函数),但它看起来很直观。