Using Look up Tables in Python

Using Look up Tables in Python

I am using python to automate a piezoelectric droplet generator. For each value of a pulse length, a suitable value of voltage will be there to produce a signal to give away a droplet. This value of voltage keeps changing in every run(for example, + or -10). So I have a database of different value of voltages for every pulse length.

I would like to know some things about using lookup tables in python. For my task, I want to pick a random pulse length from 15 to 70, and associate this value with a particular range of voltages from the database (for example: for a value 17, I would like the program to access the lookup table and return a range of voltages 35-50). Is it possible to take the entire range and not just a single value. Since, I am new to coding and python, I am not really sure. Any help is welcome. Thank you.

7

3 Answers

Since we are not given any further information about what ranges should be associated with which values, I assume you will transfer my answer to your own problem.

Look-up-Tables are called dictionary in python. They are indicated by curly brackets.

Easy example:

myDict = {1: [1, 2, 3, 4, 5],
          2: [2, 3, 4, 5, 6],
          3: [3, 4, 5, 6, 7]}

Here you create a dictionary with three entries: 1, 2, 3. Each of these entries has a range associated with it. In the example it is of logic range(i, i+5).

You inquire your "Look-Up-Table" just like a list:

print(myDict[2])
>>> [2, 3, 4, 5, 6]

(Note how [2] is not index #2, but actually the value 2 you were looking for)

Often you do not want to create a dictionary by hand, but rather want to construct it automatically. You can e.g. combine two lists of the same length to a dictionary, by using dict with zip:

indices = range(15, 76) # your values from 15 to 75
i_ranges = [range(i, i+5) for i in indices] # this constructs your ranges
myDict = dict(zip(indices, i_ranges)) # zip together the lists and make a dict from it
print(myDict[20])
>>> [20, 21, 22, 23, 24]

By the way, you are not restricted to integers and lists. You can also go like:

myFruits = {'apples': 20, 'cherries': 50, 'bananas': 23}
print(myFruits['cherries'])
>>> 50
2

numpy is your way to go, if you can put your database in a big array (and if your database is not too big)

so a quick example:

import numpy

my_array = numpy.zeros([3, 8], dtype=numpy.uint8)

this will output the following array:

array([[ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.],
   [ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.]])

from there you can access the array with the following line:

my_array[0]

it will output the first line:

array([ 0.,  0.,  0.,  0.,  0.,  0.,  0.,  0.])

you can do the same with columns:

my_array[:, 0]

it will output the first column:

array([ 0.,  0.,  0.])

using a dictionnary is also a good way.

However, numpy is written in C and is way faster than python integrated functions. And it offers a number of useful features like mean, standard deviation, where (check where a value exist in the array)

You can also create much more complicated array with numpy and explore them with ease

1

Following is a linear-interpolating lookup implementation:

from bisect import bisect_left

def lookup(x, xs, ys):
    if x <= xs[0]:  return ys[0]
    if x >= xs[-1]: return ys[-1]

    i = bisect_left(xs, x)
    k = (x - xs[i-1])/(xs[i] - xs[i-1])
    y = k*(ys[i]-ys[i-1]) + ys[i-1]

    return y

For testing:

xs = [1, 2, 4, 8, 16, 32, 64, 128, 256]
ys = [0, 1, 2, 3, 4, 5, 6, 7, 8]
i_xs = [i/1000-500 for i in range(1000000)]

start_time = time.time()
ys = [lookup(x, xs, ys) for x in i_xs]
print("%s secs" % (time.time() - start_time))

I get around 1.8secs.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Robert Thorne
Author

Robert Thorne

Robert Thorne covers electric vehicle innovations, autonomous driving systems, global mobility trends, and automotive engineering developments.