2012-04-20 11 views
3

ここに問題があります:Pythonでプラグイン可能な関数の 'daisychaining'を実装する方法は?

1)メジャーデータ(私のエレクトロニクスから読み取った1Mサンプルのようなもの)があり、それを処理チェーンで処理する必要があるとします。

2)この処理チェーンは異なる操作で構成され、スワップ/省略/異なるパラメータを持つことができます。典型的な例は、ルックアップテーブルを介して最初にそれらを渡し、次に指数関数的な適合を行い、いくつかの較正係数を乗算することです。

3)今、私はどのアルゴリズムが最良か、各段階で最良の実装を評価するのが好きです(例として、LUTは5つの方法で作成でき、どちらが最適かを知りたい)

4)これらの関数をデイジーチェーンしたいので、トップレベルのアルゴリズムを含む「クラス」を構築し、より低いレベルのアルゴリズムを含む子クラスを所有する(すなわち、指し示す)ことを意味する。

私は、二重リンクリストを使用してのようなシーケンスを生成するために考えていた

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

myCaptureClassがある

(データの取得後に)トップレベルのデータ処理モジュール(pm)をトリガする必要があります。この処理は、最初にボトム・チャイルド(lut)に深く入り、そこでデータを処理し、次に中間(expofit)、次にトップ(カリファクタ)にデータを戻してキャプチャに戻し、リクエスタにデータを戻します。

今これは、いくつかの問題があります。ネット上のどこでも

1)は、Pythonのいずれかに 2ダブルリンク・リストを使用してはならないと言われている)のデータベクトルが巨大であるため、これは、私には非常に非効率ですしたがって、私は、ジェネレータ機能を使用してソリューションを好むが、私はどのように 'プラグインのような'メカニズムを提供するか分からない。

「プラグインスタイル」とジェネレータを使用してこの問題を解決する方法を教えてもらうことができますので、ジェネレータ機能を使用するときにXメガバイトのデータを処理して「オンリクエスト」を処理する必要はありません?問題へ

おかげでたくさん

デビッド

補遺:

私がまさに自分自身を表現していなかったようです。したがって、データはVMEクレートに接続された外部HWカードによって生成されます。それらはmyCaptureClassに格納されているpythonタプルへの単一のブロック転送で 'フェッチ'されます。

適用される操作のセットは、実際にはこのタプルで表されるストリームデータです。指数関数的フィットでさえ、ストリーム操作です(各サンプルに適用される可変状態フィルターのセットです)。

私が間違って表示したパラメータは、データ処理クラスのそれぞれに付属する設定データがあり、データの操作に使用するメソッドの動作を変更するということです。

目的は、ユーザーがデータを要求したときに最終的な形式にデータを処理するために使用される(関数ではなく)daisychainedクラスをmyCaptureClassに導入することです。

メモリリソースを「節約する」ために、データを提供するためにジェネレータ機能を使用することをお勧めします。

これは、私がしたいことに最も近いものがbukzorのコードに表示されているようです。私は、関数の代わりにクラスの実装を持っているが、私はこれはちょうどを実装する化粧品だと思いますデータ操作を実現する特定のクラスの演算子を呼び出します....

+0

あなたは私たちに、入力/出力の簡単な例を与えることができれば、我々は具体的な答えを与えることができます。 – bukzor

+1

C++で二重リンクリストが必要な場合は、Pythonリストを使用する必要があります。 – bukzor

答えて

0

functionalモジュールを取得するピピそれは2つの呼び出し可能物を構成する複合関​​数を有する。これで、関数を連鎖させることができます。

このモジュールとfunctoolの両方は、部分適用のためにpartial機能を提供します。

他のどのようにも、ジェネレータ式で合成関数を使用できます。

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データのですか?

+0

これはリストの理解であり、ジェネレータではありませんが、構文はほぼ同じです。 – Marcin

+0

'list(... allthatstuff ...)'、しかしもちろんあなたは正しい。 – quodlibetor

+0

あなたは何を意味するのか分かりません。あなたのコードはすでにリストを生成しています。これをリストコンストラクタに渡すと、2番目(値の等しい)のリストが得られます。 – Marcin

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] 
+0

クラスを使用するために関数by2を修正しようとしました。私はクラスを作成し、引数データを使って '__call__'関数をオーバーライドしました。 'y = 2'がコンストラクタに渡されました。 '__call__'はmul関数として' yield'を使います。しかし、あなたは:部分的な関数を作成し、データ空の処理パイプラインを構築し、それを呼び出して同じクラスを返しますが、データは添付されています。最後の 'list(pp(..))'コマンドは、各関数を呼び出す '__iter__'を呼び出します。関数がクラスの場合、 '__call__'を呼び出す必要があります。驚くべきことにクラスが反復可能であると期待しているため、何かが間違っています。なにが問題ですか? –

+0

フルソース:http://belohrad.ch/tmp/daisychain.py –

+0

@DavidBelohrad:[gist](https://gist.github.com/)または[pocoo pastein](http:// paste.pocoo.org/)。それは他の読者のためにコンテンツを保存するのに役立ち、返信を簡単にします。 – bukzor

関連する問題