Python 有效地计算平方差之和
这是一个循环,用于提取两幅图像的RGB值,并计算所有三个通道的平方差之和。 直接在my main.py中运行此代码需要0.07秒。如果我在这个.pyx文件中运行它,速度会降低到1秒。我已经读过cdef函数,但是我没有成功地传递数组。如能帮助您将此函数转换为cdef函数,我们将不胜感激。我真的需要这个循环越快越好Python 有效地计算平方差之和,python,performance,numpy,cython,Python,Performance,Numpy,Cython,这是一个循环,用于提取两幅图像的RGB值,并计算所有三个通道的平方差之和。 直接在my main.py中运行此代码需要0.07秒。如果我在这个.pyx文件中运行它,速度会降低到1秒。我已经读过cdef函数,但是我没有成功地传递数组。如能帮助您将此函数转换为cdef函数,我们将不胜感激。我真的需要这个循环越快越好 from cpython cimport array import array import numpy as np cimport numpy as np def fittnes(O
from cpython cimport array
import array
import numpy as np
cimport numpy as np
def fittnes(Orginal, Mutated):
Fittnes = 0
for x in range(0, 299):
for y in range(0, 299):
DeltaRed = (Orginal[x][y][0] - Mutated[x][y][0])
DeltaGreen = (Orginal[x][y][1] - Mutated[x][y][1])
DeltaBlue = (Orginal[x][y][2] - Mutated[x][y][2])
Fittnes += (DeltaRed * DeltaRed + DeltaGreen * DeltaGreen + DeltaBlue * DeltaBlue)
return Fittnes
My Main.py函数调用
NewScore = cythona.fittnes(numpy.array(Orginal), numpy.array(MutatedImage))
让我有兴趣了解加速数字,所以我将此作为解决方案发布。因此,如注释中所述/讨论的,如果输入是NumPy数组,您可以使用本机NumPy工具,在本例中也是如此-
out = ((Orginal - Mutated)**2).sum()
sub = Orginal - Mutated
out = np.einsum('ijk,ijk->',sub,sub)
您也可以将非常高效的方法用于相同的任务,如下所示-
out = ((Orginal - Mutated)**2).sum()
sub = Orginal - Mutated
out = np.einsum('ijk,ijk->',sub,sub)
运行时测试
定义函数-
def org_app(Orginal,Mutated):
Fittnes = 0
for x in range(0, Orginal.shape[0]):
for y in range(0, Orginal.shape[1]):
DR = (Orginal[x][y][0] - Mutated[x][y][0])
DG = (Orginal[x][y][1] - Mutated[x][y][1])
DB = (Orginal[x][y][2] - Mutated[x][y][2])
Fittnes += (DR * DR + DG * DG + DB * DB)
return Fittnes
def einsum_based(Orginal,Mutated):
sub = Orginal - Mutated
return np.einsum('ijk,ijk->',sub,sub)
def dot_based(Orginal,Mutated): # @ali_m's suggestion
sub = Orginal - Mutated
return np.dot(sub.ravel(), sub.ravel())
def vdot_based(Orginal,Mutated): # variant of @ali_m's suggestion
sub = Orginal - Mutated
return np.vdot(sub, sub)
时间安排-
In [14]: M,N = 100,100
...: Orginal = np.random.rand(M,N,3)
...: Mutated = np.random.rand(M,N,3)
...:
In [15]: %timeit org_app(Orginal,Mutated)
...: %timeit ((Orginal - Mutated)**2).sum()
...: %timeit einsum_based(Orginal,Mutated)
...: %timeit dot_based(Orginal,Mutated)
...: %timeit vdot_based(Orginal,Mutated)
...:
10 loops, best of 3: 54.9 ms per loop
10000 loops, best of 3: 112 µs per loop
10000 loops, best of 3: 69.8 µs per loop
10000 loops, best of 3: 86.2 µs per loop
10000 loops, best of 3: 85.3 µs per loop
In [16]: # Inputs
...: M,N = 1000,1000
...: Orginal = np.random.rand(M,N,3)
...: Mutated = np.random.rand(M,N,3)
...:
In [17]: %timeit org_app(Orginal,Mutated)
...: %timeit ((Orginal - Mutated)**2).sum()
...: %timeit einsum_based(Orginal,Mutated)
...: %timeit dot_based(Orginal,Mutated)
...: %timeit vdot_based(Orginal,Mutated)
...:
1 loops, best of 3: 5.49 s per loop
10 loops, best of 3: 63 ms per loop
10 loops, best of 3: 23.9 ms per loop
10 loops, best of 3: 24.9 ms per loop
10 loops, best of 3: 24.9 ms per loop
你的cython密码在哪里?这是cython密码。从my main.py调用它如果输入数组是NumPy数组,你可以只使用
((原始-变异)**2).sum()
来实现超高速。什么是(**2)意味着我在你的代码中看不到任何cython特定的东西,但正如Divakar建议的那样,你可以单独使用NumPy来显著加快代码速度…或者只使用np.dot(sub.ravel)(),sub.ravel())
@ali_m Nice!那也行!把它作为解决方案?无论哪种方式,都想将其添加到基准测试中。与基于einsum_的测试相比,np.dot(sub.ravel(),sub.ravel())的速度有多快?@Funktiona啊,是的!我认为如果您不使用float64
,则使用np.einsum
的值会有所不同。您的输入数据类型是什么?@Funktiona您可以通过np.einsum
了解值不一致的情况。