3

这是问题所在:

1)假设我有一些测量数据(比如从我的电子设备中读取的 1Msample),我需要通过处理链处理它们。

2)这个处理链由不同的操作组成,可以交换/省略/具有不同的参数。一个典型的例子是获取这些数据,首先通过查找表传递它们,然后进行指数拟合,然后乘以一些校准因子

3) 现在,由于我不知道哪种算法最好,我想在每个阶段评估最佳可能实现(例如,LUT 可以通过 5 种方式生成,我想看看哪一种是最好的)

4)我想菊花链这些功能,我会构造一个包含顶级算法的“类”并拥有(即指向)子类,包含较低级别的算法。

我正在考虑使用双链表并生成如下序列:

myCaptureClass.addDataTreatment(pmCalibrationFactor(opt, pmExponentialFit (opt, pmLUT (opt))))

其中 myCaptureClass 是负责数据采集的类,它也应该(在采集数据之后)触发顶级数据处理模块 (pm)。该处理将首先深入到底部子级(lut),在那里处理数据,然后是中间(expofit),然后是顶部(califactors)并将数据返回给捕获,捕获将数据返回给请求者。

现在这有几个问题:

1)网上到处都说在python中不应该使用双链表 2)这在我看来效率很低,因为数据向量很大,因此我更喜欢使用生成器函数的解决方案,但我不确定如何提供“插件式”机制。

有人可以给我一个提示如何使用“插件样式”和生成器来解决这个问题,这样我就不需要处理 X 兆字节数据的向量并在使用生成器函数时“按需”处理它们是正确的?

多谢

大卫

问题的补充:

看来我并没有准确地表达自己。因此:数据由插入 VME crate 的外部硬件卡生成。它们在单个块传输中“获取”到存储在 myCaptureClass 中的 python 元组。

要应用的操作集实际上是在一个流数据上,由这个元组表示。甚至指数拟合也是流操作(它是应用于每个样本的一组可变状态过滤器)。

我错误地显示的参数'opt'是为了表达,每个数据处理类都有一些配置数据,并修改用于操作数据的方法的行为。

目标是在 myCaptureClass 中引入一个菊花链类(而不是函数),当用户请求数据时,我们用来将“原始”数据处理成最终形式。

为了“节省”内存资源,我认为使用生成器函数来提供数据可能是个好主意。

从这个角度来看,似乎与我想做的最接近的匹配显示在 bukzor 的代码中。我更喜欢有一个类实现而不是函数,但我想这只是在特定类中实现调用运算符的装饰性东西,它实现了数据操作......

4

3 回答 3

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]
于 2012-04-20T16:24:23.613 回答
0

functional从 pypi获取模块。它有一个组合函数来组合两个可调用对象。这样,您可以将功能链接在一起。

既是那个模块,又functool是提供一个partial函数,用于部分应用。

您可以像使用其他任何函数一样在生成器表达式中使用组合函数。

于 2012-04-20T15:35:39.150 回答
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数据?

于 2012-04-20T15:42:01.153 回答