python循环迭代使用numpy简化

python循环迭代使用numpy简化,python,arrays,numpy,Python,Arrays,Numpy,我用python编写代码已经有一段时间了,但现在我面临一些严重的代码性能问题(因为在矩阵上迭代的循环),我决定使用numpy来加快速度并学习更多内容 我仍然掌握着伪装的窍门,这就是为什么我在这里。这就是我试图简化的代码。我使用outSum作为累加器,然后在gX和gY的值不在同一位置时,我运行testposabibleCentersformula并将累积结果存储在outSum outSum = np.zeros((len(gX),len(gX[0])), np.uint8) outCols, ou

我用python编写代码已经有一段时间了,但现在我面临一些严重的代码性能问题(因为在矩阵上迭代的循环),我决定使用numpy来加快速度并学习更多内容

我仍然掌握着伪装的窍门,这就是为什么我在这里。这就是我试图简化的代码。我使用
outSum
作为累加器,然后在gX和gY的值不在同一位置时,我运行
testposabibleCentersformula
并将累积结果存储在
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操作matrixes元素,我需要它们

事先谢谢

编辑: 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没有相同的长度,因此我不能这样操作它们。我错过了什么?哦,还是没有第一段代码的线索

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
值。同样,通过反复试验,我发现我想要的是
最大值
而不是
最大值

它不能保证是正确的,因为我没有你的原始函数的工作副本。但由于它运行并产生正确的输出,这是一个很好的起点

这是一个中间版本:

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

我没有让它运行,但它帮助我发现了问题。

如果你可以以任何顺序(或并行)迭代
cx
cy
(并且
len(or)
对所有
cy
都是相同的),那么使用
numpy
编写
testPossibleCentersFormula
应该是很简单的。举一个小例子,比如4x3,其中
cy
cx
[0,1,2,3]
[0,1,2]
,试着用整个数组来表示计算,而不仅仅是单独的。多亏了你的提示,我想到了一些东西,但我有点卡住了。你能再把我推到正确的方向吗?我现在要测试一下,告诉你是否可以,但现在,谢谢一个文奇用你的两个cose创造了一个混合版本。看起来很好用。现在我必须进一步研究你的解决方案。再次感谢。将其标记为答案。你能给我更多关于第一段代码的提示吗?