我已经在python中编写了一段时间,但现在我面临一些严重的代码性能问题(因为循环遍历矩阵)而且我决定使用numpy加速它并学习一点更多。
我仍然处于掩饰之中,这就是我在这里的原因。这是我试图简化的代码。我使用outSum
作为累加器,然后gX和gY的值在同一位置不为零,我运行testPossibleCentersFormula
并将累积结果存储在outSum
outSum = np.zeros((len(gX),len(gX[0])), np.uint8)
outCols, outRows = outSum.shape
for y in range(len(gX)):
Xr = gX[y]
Yr = gY[y]
for x in range(len(Xr)):
grX = Xr[x]
grY = Yr[x]
if (grX == 0.0 and grY == 0.0):
continue
outSum = testPossibleCentersFormula(x, y, weight, grX, grY, outSum)
我试图像这样掩饰它
gX_zero = gX[:,0] == 0
gY_zero = gY[:,0] == 0
gXgY_zero = np.logical_not(np.logical_and(gX_zero, gY_zero))
但我不知道如何在此之后调用我的功能。
我期待也简化testPossibleCentersFormula
函数本身,因为它缺少numpy
def testPossibleCentersFormula(x, y, weight, gx, gy, out):
#for all possible centers
for cy in range(len(out)):
Or = out[cy]
Wr = weight[cy]
for cx in range(len(Or)):
if (x == cx and y == cy):
continue
#create a vector from the possible center to the gradient origin
dx = x - cx;
dy = y - cy;
#normalize d
magnitude = math.sqrt((dx * dx) + (dy * dy))
dx = dx / magnitude
dy = dy / magnitude
dotProduct = dx*gx + dy*gy
dotProduct = max(0.0, dotProduct)
#square and multiply by the weight
if (kEnableWeight):
Or[cx] += dotProduct * dotProduct * (Wr[cx]/kWeightDivisor)
else:
Or[cx] += dotProduct * dotProduct
return out
这里的问题是我真的不知道如何处理这些索引,因为我需要使用它们,如果我想用numpy元素方式操作矩阵。
事先谢谢!
编辑:
来自hpaulj的评论让我思考,我来简化testPossibleCentersFormula
这样的事情:
def testPossibleCentersFormulaEX(x, y, weight, gx, gy, out):
cx = np.arange(len(out))
cy = np.arange(len(out[0]))
dx = x - cx
dy = y - cy
mags = np.sqrt(np.square(dx) + np.square(dy))
dx = np.divide(dx, mags)
dy = np.divide(dx, mags)
dotProduct = dx * gx + dy * dy
np.maximum(0.0, dotProduct)
if(kEnableWeight):
out += np.multiply(np.square(dotProduct),(weight/kWeightDivisor))
else:
out += np.square(dotProduct)
return out
现在的问题是,当然,dx和dy的长度不一样,因此我无法像那样操作它们。我在这里错过了什么?哦,仍然不知道第一段代码。
答案 0 :(得分:0)
import numpy as np
n,m = 4,5
out = np.zeros((n,m))
x, y = 1,2
gx,gy=.1,.3
weight = False
def test(x,y, weight, gx, gy, out):
N,M=np.meshgrid(np.arange(n),np.arange(m), indexing='ij')
# N,M shape match out
dy = y-N
dx = x-M
mag = mag=np.sqrt((dx*dx)+(dy*dy))
mag[mag==0]=1 # take care of div by 0 problem
dx = dx/mag
dy = dy/mag
dotp=dx*gx + dy*gy
dotp=np.maximum(0,dotp)
out[:] = dotp
test(x,y,weight, gx,gy,out)
print(out)
生成一个类似的数组:
In [121]: run stack31064314.py
[[ 0.31304952 0.3 0.2236068 0.14142136 0.08320503]
[ 0.28284271 0.3 0.14142136 0.04472136 0. ]
[ 0.1 0. 0. 0. 0. ]
[ 0. 0. 0. 0. 0. ]]
我在Ipython中以交互方式开发 - 创建meshgrid
数组(在2d中表示cx和cy),更改为ij
索引以匹配out
。测试计算也有助于思考如何解决0
值。同样,我通过反复试验发现我希望maximum
不是max
。
不保证是正确的,因为我没有原始功能的工作副本。但由于它运行并产生正确的形状输出,因此它是一个很好的起点。
这是一个中间版本:
def testPossibleCentersFormula(x, y, weight, gx, gy, out):
out = np.empty((n,m))
cy = np.arange(out.shape[0])
cx = np.arange(out.shape[1])
dx = x - cx # len m
dy = y - cy # len n
magnitude = np.sqrt((dx*dx)[None,:]+(dy*dy)[:,None]) # (n,m) array
dx = dx[None,:] / magnitude
dy = dy[:,None] / magnitude
# problem one value of magnitude will be 0, (x,y)
dotProduct = dx*gx + dy*gy # gx,gy scalars
dotProduct = np.max(0, dotProduct) # make sure it is right max
# ie clip dotProduct a 0
dotProduct = dotProduct * dotProduct
if kEnableWeight:
# Wr - (n,m) array
dotProduct *= (Wr/kWeightDivisor)
Out[:,:] = dotProduct
我没有让它运行,但它帮助我确定了问题。