3

ここに問題があります:

1)いくつかの測定データ(電子機器から読み取った1Mサンプルなど)があり、それらを処理チェーンで処理する必要があるとします。

2)この処理チェーンは、スワップ/省略/異なるパラメーターを持つことができるさまざまな操作で構成されています。典型的な例は、このデータを取得し、最初にルックアップテーブルを介してそれらを渡し、次に指数フィットを実行し、次にいくつかのキャリブレーション係数を乗算することです。

3)さて、どのアルゴリズムが最適かわからないので、各段階で可能な限り最良の実装を評価したいと思います(たとえば、LUTは5つの方法で作成でき、どれが最適かを確認したいと思います。 )。

4)これらの関数をデイジーチェーン化して、最上位のアルゴリズムを含む「クラス」を構築し、下位レベルのアルゴリズムを含む子クラスを所有(つまりポインティング)したいと思います。

私はdouble-linked-listを使用して、次のようなシーケンスを生成することを考えていました。

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

ここで、myCaptureClassはデータ取得を担当するクラスであり、(データが取得された後)トップレベルのデータ処理モジュール(pm)をトリガーする必要があります。この処理は、最初に下位の子(lut)に深く入り、そこでデータを処理し、次に中間(expofit)、次に上位(califactors)になり、データをキャプチャに返します。これにより、データがリクエスターに返されます。

現在、これにはいくつかの問題があります。

1)ネット上のどこでも、Pythonでは二重リンクリストを使用すべきではないと言われています2)データベクトルが巨大であるため、これは非常に非効率的であるように思われます。したがって、ジェネレータ関数を使用したソリューションを好みますが、よくわかりません「プラグインのような」メカニズムを提供する方法。

誰かが「プラグインスタイル」とジェネレーターを使用してこれを解決する方法のヒントを教えてもらえますか?ジェネレーター関数を使用するときに正しいように、Xメガバイトのデータのベクトルを処理して「要求に応じて」処理する必要はありませんか?

どうもありがとう

デビッド

問題への補遺:

自分を正確に表現していなかったようです。したがって、データはVMEクレートに接続された外部HWカードによって生成されます。それらは、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

functionalpypi からモジュールを取得します。2 つの callable を構成する構成関数があります。これにより、関数を連鎖させることができます。

そのモジュールと、部分適用のため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 に答える