在 Python 中使用查找表
Using Look Up Tables in Python
我正在使用 python 来自动化压电液滴发生器。对于每个脉冲长度值,都会有一个 suitable 电压值来产生信号以释放液滴。该电压值每隔运行(例如+或-10)不断变化。所以我有一个数据库,其中包含每个脉冲长度的不同电压值。
我想知道一些关于在 python 中使用查找 table 的事情。对于我的任务,我想选择一个从 15 到 70 的随机脉冲长度,并将该值与数据库中的特定电压范围相关联(例如:对于值 17,我希望程序访问查找 table 和 return 电压范围 35-50)。是否可以取整个范围而不仅仅是一个值。因为,我是编码新手并且 python,所以我不太确定。欢迎任何帮助。谢谢。
由于我们没有得到关于哪些范围应该与哪些值相关联的任何进一步信息,我假设您会将我的答案转移到您自己的问题上。
查找表在 python 中被称为 dictionary
。它们用大括号表示。
简单示例:
myDict = {1: [1, 2, 3, 4, 5],
2: [2, 3, 4, 5, 6],
3: [3, 4, 5, 6, 7]}
在这里您创建了一个包含三个条目的字典:1、2、3。每个条目都有一个与之关联的范围。在例子中是逻辑range(i, i+5)
.
你查询你的"Look-Up-Table"就像一个列表:
print(myDict[2])
>>> [2, 3, 4, 5, 6]
(注意 [2]
不是索引 #2,而是您要查找的值 2
)
通常您不想手动创建字典,而是希望自动构建它。你可以例如通过使用 dict
和 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]
顺便说一下,您不限于整数和列表。你也可以这样:
myFruits = {'apples': 20, 'cherries': 50, 'bananas': 23}
print(myFruits['cherries'])
>>> 50
numpy 是你的选择,如果你可以把你的数据库放在一个大数组中(如果你的数据库不是太大)
举个简单的例子:
import numpy
my_array = numpy.zeros([3, 8], dtype=numpy.uint8)
这将输出以下数组:
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.]])
从那里您可以使用以下行访问数组:
my_array[0]
它将输出第一行:
array([ 0., 0., 0., 0., 0., 0., 0., 0.])
您可以对列执行相同的操作:
my_array[:, 0]
它将输出第一列:
array([ 0., 0., 0.])
用字典也是个好方法。
但是,numpy 是用 C 编写的,比 python 集成函数快得多。它提供了许多有用的功能,例如均值、标准差,其中(检查数组中存在值的位置)
您还可以使用 numpy 创建更复杂的数组并轻松探索它们
以下是 linear-interpolating 查找实现:
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
用于测试:
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))
我大约需要 1.8 秒。
我正在使用 python 来自动化压电液滴发生器。对于每个脉冲长度值,都会有一个 suitable 电压值来产生信号以释放液滴。该电压值每隔运行(例如+或-10)不断变化。所以我有一个数据库,其中包含每个脉冲长度的不同电压值。
我想知道一些关于在 python 中使用查找 table 的事情。对于我的任务,我想选择一个从 15 到 70 的随机脉冲长度,并将该值与数据库中的特定电压范围相关联(例如:对于值 17,我希望程序访问查找 table 和 return 电压范围 35-50)。是否可以取整个范围而不仅仅是一个值。因为,我是编码新手并且 python,所以我不太确定。欢迎任何帮助。谢谢。
由于我们没有得到关于哪些范围应该与哪些值相关联的任何进一步信息,我假设您会将我的答案转移到您自己的问题上。
查找表在 python 中被称为 dictionary
。它们用大括号表示。
简单示例:
myDict = {1: [1, 2, 3, 4, 5],
2: [2, 3, 4, 5, 6],
3: [3, 4, 5, 6, 7]}
在这里您创建了一个包含三个条目的字典:1、2、3。每个条目都有一个与之关联的范围。在例子中是逻辑range(i, i+5)
.
你查询你的"Look-Up-Table"就像一个列表:
print(myDict[2])
>>> [2, 3, 4, 5, 6]
(注意 [2]
不是索引 #2,而是您要查找的值 2
)
通常您不想手动创建字典,而是希望自动构建它。你可以例如通过使用 dict
和 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]
顺便说一下,您不限于整数和列表。你也可以这样:
myFruits = {'apples': 20, 'cherries': 50, 'bananas': 23}
print(myFruits['cherries'])
>>> 50
numpy 是你的选择,如果你可以把你的数据库放在一个大数组中(如果你的数据库不是太大)
举个简单的例子:
import numpy
my_array = numpy.zeros([3, 8], dtype=numpy.uint8)
这将输出以下数组:
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.]])
从那里您可以使用以下行访问数组:
my_array[0]
它将输出第一行:
array([ 0., 0., 0., 0., 0., 0., 0., 0.])
您可以对列执行相同的操作:
my_array[:, 0]
它将输出第一列:
array([ 0., 0., 0.])
用字典也是个好方法。
但是,numpy 是用 C 编写的,比 python 集成函数快得多。它提供了许多有用的功能,例如均值、标准差,其中(检查数组中存在值的位置)
您还可以使用 numpy 创建更复杂的数组并轻松探索它们
以下是 linear-interpolating 查找实现:
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
用于测试:
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))
我大约需要 1.8 秒。