简体   繁体   中英

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.

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 eg 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

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

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM