0

I am stuck trying to figure out how to avoid doing 2 loops while doing some analysis on an image. Its a square image (same dimension in the x and y). The current way its set up its that for each pixel, in the array "stars", the first coordinate is the x position, the second coordinate is the y position, and the third coordinate is the brightness of the pixel. I know there must be a far far superior way to set this up but every thing I try just works when i=j (giving me essentially only the diagonal of this matrix). How do I do this better?!

def firstmoment(stars,bins):
    xsum=0.0
    ysum=0.0
    itot=0.0
    for i in range(0, bins):
        for j in range(0, bins):
            xsum=xsum+stars[i][j][0]*stars[i][j][2]
            ysum=ysum+stars[i][j][1]*stars[i][j][2]
            itot=itot+stars[i][j][2]
    x0=xsum/itot
    y0=ysum/itot
    return x0, y0, itot
3
  • 1
    Please provide some representative example data for stars and bins. See how to make a minimal reproducible example. Also include expected output for the sample data you provide (that way answers can verify their correctness). Commented Jul 28, 2018 at 6:08
  • To be honest I'm not that sure you can reduce the 2 loops to one loop only, unless there are very particular conditions [e.g. working on the diagonal, like you already said]. The image is a 2D territory and then in general you can't escape running a loop along its 2 dimensions. In the same way as you can't generally skip two loops when working on a square matrix Commented Jul 28, 2018 at 6:16
  • 1
    looks like xsum=np.sum(stars[:,:,0]*stars[:,:,2]). etc Commented Jul 28, 2018 at 6:34

1 Answer 1

1

Let's just focus on the x part, ignoring y because it works the same way.

def firstmoment(stars, bins):
    xsum = 0.0
    itot = 0.0
    for i in range(bins):
        for j in range(bins):
            xsum += stars[i][j][0] * stars[i][j][2]
            itot += stars[i][j][2]
    x0 = xsum / itot
    return x0, itot

stars is a 3D array indexed as [x, y, luminance]. At the end, itot is the sum of the luminance values, which is trivially stars[:bins,:bins,2].sum(). Using a similar transformation for xsum, we get:

def firstmoment(stars, bins):
    xsum = (stars[:bins,:bins,0] * stars[:bins,:bins,2]).sum()
    itot = stars[:bins,:bins,2].sum()
    x0 = xsum / itot
    return x0, itot
Sign up to request clarification or add additional context in comments.

1 Comment

thank you for helping me get rid of the loops! this works like a charm and is definitely faster :)

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.