问题在于:
1)假设我有一些测量数据(例如从我的电子产品中读取1Msample),我需要通过处理链处理它们。
2)该处理链由不同的操作组成,可以交换/省略/具有不同的参数。一个典型的例子是获取这些数据,首先通过查找表传递它们,然后进行指数拟合,然后乘以一些校准因子
3)现在,由于我不知道哪种算法最好,我想在每个阶段评估最佳可能的实现(例如,LUT可以通过5种方式生成,我想看看哪一种是最好的)
4)我想菊花链这些函数,我将构建一个包含顶级算法的“类”,并拥有(即指向)子类,包含低级算法。
我正在考虑使用双链表并生成如下序列:
myCaptureClass.addDataTreatment(pmCalibrationFactor(opt,pmExponentialFit(opt,pmLUT(opt))))
其中myCaptureClass是负责数据处理的类,它也应该(在获取数据之后)触发顶级数据处理模块(pm)。这个处理首先深入到底层子(lut),在那里处理数据,然后是中间(expofit),然后是top(califactors)并将数据返回到捕获,这将把数据返回给请求者。
现在这有几个问题:
1)网上到处都说,在python中不应该使用双链表 2)这在我看来非常低效,因为数据向量很大,因此我更喜欢使用生成器函数的解决方案,但我不确定如何提供“插件式”机制。
有人可以给我一个提示如何使用'插件式'和生成器来解决这个问题,这样我就不需要处理X兆字节数据的向量并按需“处理它们”,这在使用生成器函数时是正确的吗?
非常感谢
大卫
问题的附录:
似乎我没有完全表达自己。因此:数据由插入VME包的外部HW卡生成。它们被“取出”到一个块传递给python元组,它存储在myCaptureClass中。要应用的操作集实际上是在由此元组表示的流数据上。甚至指数拟合也是流操作(它是在每个样本上应用的一组可变状态过滤器)。
我错误地显示的参数'opt'表示,每个数据处理类都有一些附带的配置数据,并修改用于操作数据的方法的行为。
目标是在myCaptureClass中引入一个菊花链类(而不是函数),当用户请求数据时,我们用来将'原始'数据处理成最终形式。
为了“节省”内存资源,我认为使用生成器函数提供数据可能是个好主意。
从这个角度来看,似乎与我想要做的最接近的匹配在bukzor的代码中显示。我更喜欢有一个类实现而不是函数,但我想这只是在特定类中实现调用运算符的一个美妙的东西,它实现了数据操作....
答案 0 :(得分:1)
这就是我想象你会这样做的。我希望这不完整,因为我不完全理解你的问题陈述。请让我知道我做错了什么:)
class ProcessingPipeline(object):
def __init__(self, *functions, **kwargs):
self.functions = functions
self.data = kwargs.get('data')
def __call__(self, data):
return ProcessingPipeline(*self.functions, data=data)
def __iter__(self):
data = self.data
for func in self.functions:
data = func(data)
return data
# a few (very simple) operators, of different kinds
class Multiplier(object):
def __init__(self, by):
self.by = by
def __call__(self, data):
for x in data:
yield x * self.by
def add(data, y):
for x in data:
yield x + y
from functools import partial
by2 = Multiplier(by=2)
sub1 = partial(add, y=-1)
square = lambda data: ( x*x for x in data )
pp = ProcessingPipeline(square, sub1, by2)
print list(pp(range(10)))
print list(pp(range(-3, 4)))
输出:
$ python how-to-implement-daisychaining-of-pluggable-function-in-python.py
[-2, 0, 6, 16, 30, 48, 70, 96, 126, 160]
[16, 6, 0, -2, 0, 6, 16]
答案 1 :(得分:0)
从pypi获取functional
模块。它具有组合两个callables的组合功能。有了它,你可以将功能链接在一起。
该模块和functool
都提供了partial
功能,用于部分应用。
您可以像生成任何其他函数一样在生成器表达式中使用组合函数。
答案 2 :(得分:0)
我不知道你想要什么,我觉得我应该指出你可以把你想要的任何东西放在列表理解中:
l = [myCaptureClass.addDataTreatment(
pmCalibrationFactor(opt, pmExponentialFit (opt, pmLUT (opt))))
for opt in data]
将创建一个已通过组合函数传递的新数据列表。
或者您可以创建一个用于循环的生成器表达式,这不会构造一个全新的列表,它只会创建一个迭代器。我不认为以这种方式做事有任何好处,而不是仅仅处理循环体中的数据,但看起来很有意思:
d = (myCaptureClass.addDataTreatment(
pmCalibrationFactor(opt, pmExponentialFit (opt, pmLUT (opt))))
for opt in data)
for thing in d:
# do something
pass
或opt
是数据吗?