pythonnumpynumpy-ndarray

Place pixels on a grid


I have a two dimensional numpy array: myarray=[[0,0],[1,1],[2,2]] I also have a grid of points: mygrid=[[70,70],[100,100],[30,30]]

I want to efficiently create a new array which contains points of myarrray added to the grid:

desired_result=[[70,70],[71,71],[72,72],[100,100],[101,101],[102,102],[30,30],[31,31],[32,32]]

One can imagine placing a 1x3 pixel block on the positions of the grid. If I work with a matrix which consists of np.ones(dimensions), swapping the ones for zeros at place of the desired_result creates a grid of 1x3 pixel blocks. One can use coordinates that describe a circle/geometrical shape at the place of myarray, which would then create a grid of circles/geometrical shapes.


Solution

  • For the last part of the question the answer is straightforward. That is what broadcasting is for

    myarray=[[0,0],[1,1],[2,2]] 
    mygrid=[[70,70],[100,100],[30,30]]
    result = (np.array(myarray)[None,:,:] + np.array(mygrid)[:,None,:]).reshape(-1,2)
    

    Some explanations:
    A=np.array(myarray)[None,:,:] is [[[0,0],[1,1],[2,2]]], that is a 3D array, whose first dimension has only 1 element (myarray itself). So a 1×3×2 array, such as A[0,i,j] = myarray[i,j]
    B=np.array(mygrid)[:,None,:] is [[[70,70]],[[100,100]],[[30,30]]], so a 3D array, whose 2nd dimension has only 1 element each time. So a 3×1×2 array such as B[i,0,j] = mygrid[i,j].

    And because of broadcasting, adding a size-1 array X to a size-n array Y adds the element on each of the n elements of Y (array([12]) + array([10,20,30]) is array([22,32,42])), and that for each axis, the result of A+B is a 3×3×2 array, whose element (A+B)[i,j,k] is A[0,j,k]+B[i,0,k] = myarray[j,k]+mygrid[i,k]. So what you want, or almost so.

    You want to have those in sequence, that is a 9×2 array. Which is achieved by reshaping the result to a 9×2 shape (I've used a -1×2 shape, since I am allowed to replace one of the dimensions size by -1, which is then computed automatically. So, I was too lazy to compute the total size, len(mygrid)*len(myarray), and since 2 is a constant here, it was easy to rely on simply this -1.