2013-01-24 54 views
2

我構建了一個粒子過濾器來處理來自pandas DataFrame的數據。濾波器背後的想法是迭代估計最佳結果(類似於蒙特卡羅)。我有一個基類ExperimentalData()它有基本的方法來收集數據等。我打算建立另一個類有不同的過濾器。過濾器的類始終來自ExperimentalData()在嵌套類中使用對象繼承對象來運行迭代

在我的class ParFilter(ExperimentalData)裏面,我有方法def particleFilter(self, N=1000)運行過濾器並獲得所需的估計值。由於我需要在迭代期間訪問數據,因此我在內部生成class Iterator(object),我將在這裏處理數據。

我在將數據傳遞到類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,它應該是在Iterator代替0.727060相同。所以我創造了新的對象。

我無法弄清楚如何獲得原始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'和一些更多,但沒有結果。

(我必須使用熊貓數據幀作爲我的基類是相當大的,得到的大數據幀不喜歡爲例)

回答

2

的問題你的代碼是內部類嘗試訪問外部的成員變量類。這是不可能的,因爲他們都使用self來引用他們當前的實例,而內部類的self參數會影響外部類的self。您需要爲其中一個使用不同的名稱。

雖然你可以在實際的方法之一,使用不同的名稱作爲第一個參數的名字,我建議只是一個額外的名稱綁定到外部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() 

這有效,但它可能不是最好的設計。嵌套類是不可序列化的,可能非常難以調試,應儘可能避免。

一個更好的想法是UNNEST類和簡單地傳遞你從外部類的內部類的構造函數,其中一個參考,可以保存爲一個成員變量所需的數據:

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