Search code examples
pythonpython-3.xnumpylookuplookup-tables

Lookup table using 2 columns to identify rows


I have a numpy lookup table of xy coordinates, where columns 0=xa, 1=ya, 2=xb, 3=yb. I'm trying to use xa and ya (cols 0 & 1) to act as the pair of elements that enable the looking up of xb and yb (cols 2 & 3), which are the actual xy coordinates I want to use.

lookup=
[[0,    0,  0,      0]
[2,     0,  1.98,   -0.01]
[4,     0,  3.99,   -0.01]
[6,     0,  6.03,   -0.01]
[8,     0,  8.02,   -0.03]
[10,    0,  9.98,   -0.01]
[12,    0,  11.99,  0]
[14,    0,  13.99,  0]
[0,     1,  -0.03,  0.88]
[2,     1,  1.95,   0.86]
[4,     1,  3.97,   0.85]
[6,     1,  5.97,   0.87]
[8,     1,  7.96,   0.86]
[10,    1,  9.95,   0.92]
[12,    1,  11.95,  0.92]
[14,    1,  13.97,  0.87]]

I have a table with data that has x and y locations in the format xa ya, that I wish to to change to xb yb using the lookup table:

gridloc=
[[6,    0]
 [8,    0]
 [8,    0]
 [10,   0]
 [8,    1]
 [10,   1]
 [12,   1]
 [14,   1]

So I want the result to be this:

newloc=
[[6.03,   -0.01]
 [8.02,   -0.03]
 [8.02,   -0.03]
 [9.98,   -0.01]
 [7.96,   0.86]
 [9.95,   0.92]
 [11.95,  0.92]
 [13.97,  0.87]]

I've tried using this to try to create a dictionary, but I get an error:

mapping = dict(zip(lookup[:,0:2], range(len(lookup))))

Traceback (most recent call last):

  File "<ipython-input-12-528fb6616ce0>", line 1, in <module>
    mapping = dict(zip(lookup[:,0:2], range(len(lookup))))

TypeError: unhashable type: 'numpy.ndarray'

Does anyone have any advice, please? Should my tables be in numpy in the first place? Is dict the way to solve the problem?


Solution

  • One option is to do it using Pandas indexing capabilities:

    import numpy as np
    import pandas as pd
    
    lookup = np.array(
        [[0,    0,  0,      0],
         [2,     0,  1.98,   -0.01],
         [4,     0,  3.99,   -0.01],
         [6,     0,  6.03,   -0.01],
         [8,     0,  8.02,   -0.03],
         [10,    0,  9.98,   -0.01],
         [12,    0,  11.99,  0],
         [14,    0,  13.99,  0],
         [0,     1,  -0.03,  0.88],
         [2,     1,  1.95,   0.86],
         [4,     1,  3.97,   0.85],
         [6,     1,  5.97,   0.87],
         [8,     1,  7.96,   0.86],
         [10,    1,  9.95,   0.92],
         [12,    1,  11.95,  0.92],
         [14,    1,  13.97,  0.87]])
    gridloc = np.array(
        [[6,    0],
         [8,    0],
         [8,    0],
         [10,   0],
         [8,    1],
         [10,   1],
         [12,   1],
         [14,   1]])
    
    idx = pd.MultiIndex.from_arrays([lookup[:, 0], lookup[:, 1]], names=('xa', 'ya'))
    df = pd.DataFrame(lookup[:, 2:], columns=('xb', 'yb'), index=idx)
    # This should work but is not implemented for multidimensional arrays
    # newloc = df.loc[gridloc].values
    # Converting to list of tuples works
    newloc = df.loc[list(map(tuple, gridloc))].values  # Add .copy() if need writing
    print(newloc)
    

    Output:

    [[  6.03000000e+00  -1.00000000e-02]
     [  8.02000000e+00  -3.00000000e-02]
     [  8.02000000e+00  -3.00000000e-02]
     [  9.98000000e+00  -1.00000000e-02]
     [  7.96000000e+00   8.60000000e-01]
     [  9.95000000e+00   9.20000000e-01]
     [  1.19500000e+01   9.20000000e-01]
     [  1.39700000e+01   8.70000000e-01]]