python - 使用numpy

时间:2015-06-26 03:17:40

标签: python arrays numpy

我已经在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的长度不一样,因此我无法像那样操作它们。我在这里错过了什么?哦,仍然不知道第一段代码。

1 个答案:

答案 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

我没有让它运行,但它帮助我确定了问题。