2

In a time series data, I have (x,y) coordinates for an object that evolve over a 2-D grid. For example:

(41.797, 34.0),
(42.152, 34.56),
(42.383, 36.07),
(42.505, 37.97)

How do I index the array in a way that array[x,y]=object_id. Subsequently, I'd need to go through this time-indexed 2-D grid again, and index array[x',y']=object_id_2. Where x' and y' are like a list above.

1
  • What are these objects? Are they already created? Do you need to create them? Can you modify these objects? Commented Dec 20, 2018 at 20:47

2 Answers 2

2

It is possible to index a numpy array using floating point indices, you just need to interpolate between values. Here is code that will do that, using bilinear interpolation (taken from this gist)

def subsample_image(coords, img):
    """
    Given a list of floating point coordinates (Nx2) in the image,
    return the pixel value at each location using bilinear interpolation.
    """
    if len(img.shape) == 2:
        img = np.expand_dims(img, 2)
    xs, ys = coords[:, 0], coords[:, 1]
    pxs = np.floor(xs).astype(int)
    pys = np.floor(ys).astype(int)
    dxs = xs-pxs
    dys = ys-pys
    wxs, wys = 1.0-dxs, 1.0-dys
    
    weights =  np.multiply(img[pys, pxs, :].T      , wxs*wys).T
    weights += np.multiply(img[pys, pxs+1, :].T    , dxs*wys).T
    weights += np.multiply(img[pys+1, pxs, :].T    , wxs*dys).T
    weights += np.multiply(img[pys+1, pxs+1, :].T  , dxs*dys).T
    return weights
Sign up to request clarification or add additional context in comments.

Comments

1

There are a few problems here.

First, you can't index by floats because it doesn't make any sense. Second, if you could, there is a problem with the way floats are interpreted/calculated (the reason why sometimes your results are like 3.99999999 instead of 4).

My recommendation is to index your values using a dictionary rounded to a certain number of decimals. This way you will ensure your data always matches!

Since you cannot map stuff by immutable keys, you need a tuple.

An example of how this would work:

mydict = {}

a = (41.797, 34.0)
object_a = 'A'
b = (42.152, 34.56)
object_b 'B'

mydict[round(a[0], 3), round(a[1], 3)] = object_a
mydict[round(b[0], 3), round(b[1], 3)] = object_b

print ( my_dict[round(a[0], 3), round(a[1], 3)] )
print ( my_dict[round(b[0], 3), round(b[1], 3)] )

>> 'A'
>> 'B'

If you want to update the object you simply use the rounded tuple

mydict[round(a[0], 3), round(a[1], 3)] = 'CHICKEN'


print ( my_dict[round(a[0], 3), round(a[1], 3)] )
print ( my_dict[round(b[0], 3), round(b[1], 3)] )

>> 'CHICKEN'
>> 'B'

If the code gets too messy, just add a function to round tuples:

def round_tuple(tupl, decimals=3):
    return round(tupl[0], decimals), round(tupl[1], decimals)

This way you just do this:
target = round_tuple(tup)
mydict[target] = 'CHICKEN'

Comments

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.