2

pandas DataFrame からのデータを処理するためのパーティクル フィルターを作成しています。フィルターの背後にある考え方は、反復して最良の結果を推定することです (モンテカルロに似ています)。データなどを収集するための基本的なメソッドを持つ基本クラスExperimentalData()があります。さまざまなフィルターを持つ別のクラスを構築します。フィルタのクラスは常に から派生しExperimentalData()ます。

内部には、フィルターを実行して目的の見積もりを取得するclass ParFilter(ExperimentalData)メソッドがあります。def particleFilter(self, N=1000)反復中にデータにアクセスする必要があるため、内部でデータを処理するclass Iterator(object)場所を構築します。

class にデータを渡す際に問題がありますIterator()。私はほとんどの場合、うまくいくはずだと思っていましたが、うまくいきませんでしたAttributeError: 'Iterator' object has no attribute 'myData'。最終的に、いくつかのデータを渡すことができますが、それは私が期待したのと同じデータ オブジェクトではありません。

私のコードは、例を説明するために削減されました:

import numpy as np
import pandas as pd

class ExperimentalData(object):
    def __init__(self):
        self.xTrueSource = 100
        self.yTrueSource = -7
        print 'source %s  %s' % (self.xTrueSource,self.yTrueSource)
        xSampPoints = np.arange(0,200)
        yTrueSignal = 100/(np.sqrt((self.xTrueSource - xSampPoints)**2 + (self.yTrueSource)**2))
        ySampPoints = yTrueSignal+np.random.randn(200)
        self.myData = pd.DataFrame({'x':xSampPoints,'ySamp':ySampPoints,'yTrue':yTrueSignal})
        #print self.myData
    def __str__(self, rows=2):           
        dfPrintStart = (self.myData[:rows]).to_string()
        dfPrintEnd =(self.myData[-rows:]).to_string()
        stringToPrint='\nPRINTNG INITIAL DATAFRAME FIRST %d ROWS and LAST %d ROWS \n %s\n...\n%s\n'\
                        % (rows, rows, dfPrintStart, dfPrintEnd)
        return stringToPrint

class ParFilter(ExperimentalData):

    def particleFilter(self, N=1000):
        '''function runs particle filter'''
        class Iterator(object):
            def __init__(self):
                '''initialise all values for iteration'''
                self.iteration = 0
                frameToWork = ParFilter().myData                
                print 'FROM CLASS Iterator.__init__ \n%s' % frameToWork
            def iterate(self):
                '''performing one step at the time'''
                self.iteration += 1
                print self.iteration
        myPartFilter = Iterator()
        for n in range(N):
            myPartFilter.iterate()
        return myPartFilter

if __name__ == '__main__':
    data = ParFilter()
    print data
    data.particleFilter(10)

問題は、クラスを初期化するときに特定の値を持つデータフレームがあることですが、ステップを実行するframeToWork = ParFilter().myDataと、同じデータオブジェクトを取得する代わりに、異なるデータを持つ新しいオブジェクトを生成することです。出力のスナップショット:

PRINTNG INITIAL DATAFRAME FIRST 2 ROWS and LAST 2 ROWS 
   x     ySamp     yTrue
0  0  0.510414  0.997559
1  1  1.522934  1.007585
...
       x     ySamp     yTrue
198  198  1.508216  1.017815
199  199  2.409181  1.007585

FROM CLASS Iterator.__init__ 
   x     ySamp     yTrue
0  0  0.727060  0.997559
1  1  0.631976  1.007585

初期化中の最初の値ySampは 0.510414 であり、0.727060 ではなく同じである必要がありIteratorます。だから私は新しいオブジェクトを作成します。

myData元のオブジェクトを取得する方法がわかりませんIterator:

    class Iterator(ParFilter):
        def __init__(self):
            '''initialise all values for iteration'''
            self.iteration = 0
            frameToWork = self.myData 

AttributeError: 'Iterator' object has no attribute 'myData'

私は試してみます:class Iterator(self.ParFilter)AttributeError: 'ParFilter' object has no attribute 'ParFilter'いくつかの結果がありますが、結果はありません。

(私の基本クラスは非常に大きく、例のように大きなデータフレームを取得していないため、パンダのデータフレームを使用する必要があります)

4

1 に答える 1

2

コードの問題は、内部クラスが外部クラスのメンバー変数にアクセスしようとしていることです。selfどちらも現在のインスタンスを参照するために使用しており、内部クラスのselfパラメータが外部クラスのをシャドウイングしているため、これは不可能ですself。それらの1つに別の名前を使用する必要があります。

いずれかのメソッドの最初のパラメーター名に実際には別の名前を使用することもできますがself、ネストされたクラスを定義する前に、外部オブジェクトに追加の名前をバインドすることをお勧めします。

class Outer(object):
    def __init__(self):
        self.foo = "foo"

    def do_stuff(self):
        outer_self = self # give an extra name to `self` that won't be shadowed

        class Inner(object):
            def __init__(self):
                 self.bar = "bar"

            def do_inner_stuff(self):
                print(outer_self.foo, self.bar) # access the outer class's data

        i = Inner()
        i.do_inner_stuff()

これは機能しますが、それでもおそらく最良の設計ではありません。ネストされたクラスはシリアル化できず、デバッグがかなり厄介になる可能性があるため、可能であれば回避する必要があります。

より良いアイデアは、クラスのネストを解除し、必要なデータを外部クラスから内部クラスのコンストラクターに渡すことです。ここで、参照をメンバー変数として保存できます。

class Outer(object):
    def __init__(self):
        self.foo = "foo"

    def do_stuff(self):
        i = Inner(self.foo) # pass relevant data to constructor
        i.do_inner_stuff()

class Inner(object):
    def __init__(self, foo):
        self.foo = foo # keep a reference to passed data
        self.bar = "bar"

    def do_inner_stuff(self):
        print(self.foo, self.bar)  # use the data
于 2013-01-24T02:20:36.530 に答える