9

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.

Vishvachi Sinha
  • 147
  • 1
  • 4
  • 10
  • 1
    How does 17 give you the range 35-50? What's the logic? What happens for other values? What codes did you try? Where did you get stuck? See [How to Ask](https://stackoverflow.com/help/how-to-ask) for more details. – Ofer Sadan May 24 '18 at 11:31
  • You are looking for a structure that is called `dictionary` in python. https://www.tutorialspoint.com/python/python_dictionary.htm – offeltoffel May 24 '18 at 11:31
  • @OferSadan : Hi, i have edited the question now. I hope this is better than before. – Vishvachi Sinha May 24 '18 at 11:39
  • @offeltoffel : Thanks. Will look into it. – Vishvachi Sinha May 24 '18 at 11:39
  • Now it's more clear, but still not enough to help you with. That would depend on what type of database those values are stored in. If it's an SQL table for example, there are simple commands for lookup that will give you the values that you want. Other types of data storage might require building that logic yourself. We have no idea what your data looks like to even begin with an answer. – Ofer Sadan May 24 '18 at 11:42
  • See the link in my first comment: the proper question for that would be: "My data is `x` and I want to do `y`, I have read and **tried** to do `z` but failed because of errors or because I'm missing something, please help" – Ofer Sadan May 24 '18 at 11:45
  • @OferSadan :Thank you. I haven't tried anything because I was clueless. I wanted to know where to begin with for which another person has suggested dictionary structure. Mine is a .csv file with one column for the pulse length values namely 15 to 70 and 12 columns with the values of corresponding voltages in each run and 1 column which has the range of voltage (45-60) found from the 12 columns of data. Is it possible to work with this? Or any other way? – Vishvachi Sinha May 24 '18 at 11:47

3 Answers3

18

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
offeltoffel
  • 2,691
  • 2
  • 21
  • 35
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

Community
  • 1
  • 1
Mael Abgrall
  • 441
  • 2
  • 6
  • 16
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.

Aykut Kllic
  • 898
  • 9
  • 14