2016-12-01 23 views
8

對於任何給定的索引,是否可以生成一個插值它的值的序列。我有一個預定義的插值方案,我希望規定,我寧願調用者不自己應用插值,以避免任何錯誤的可能性。是否可以構建一個自動插值的熊貓系列?

class InterpolatedSeries(pd.Series): 
    pass # magic? 

s = pd.Series([1, 3], index=[1, 3]) 
i = InterpolatedSeries(s, forward='nearest', backward='nearest', middle='linear') 

主叫方將收到i結果,他們現在可以要求任何價值,而且我確信他們得到了符合規定的插值方案的價值。插值當然不是可預先計算的(因爲我們不知道他們會提前請求哪些點)還是可緩存的(因爲我們不知道他們要求多少點),但重要的是沒有併發症爲來電者。

這可能嗎?

>>> i[[0, 0.11234, 1, 2, 2.367, 3, 4]] 
... pd.Series([1, 1, 1, 2, 2.367, 3, 3], index=[0, 0.11234, 1, 2, 2.367, 3, 4]) 
+0

你可以更具體地說明你爲什麼希望這是pd.Series的子類嗎? – DSM

+0

這個意圖是讓庫函數返回一個爲了所有目的而與pd.Series具有相同接口的東西。 因此,用戶可以.to_csv或groupby等,如果他們想。 – poulter7

+0

查閱python魔術方法。您可能只需在設置項目值時進行插值。當你改變一個項目值'i [0] = 1'時調用'__setitem__',所以在'__setitem__'方法中,在設置它們之前插入值,或者設置值插值所有值然後重置價值。當有人要求值'variable = i [0]'時,你也可以使用'__getitem__'進行插值。 – HashSplat

回答

5

使用__getitem__。它被稱爲蟒魔術方法http://www.diveintopython3.net/special-method-names.html

class InterpolatedSeries(pd.Series): 
    def __init__(self, values, forward='nearest', backward='nearest', middle='linear'): 
     super().__init__(values) 
     self.forward = forward 
     self.backward = backward 
     self.middle = middle 

    def __getitem__(self, key): 
     # get the stored values 
     values = super().__getitem__(key) 
     # Do interpolation 
     return values 

class InterpolatedSeries(pd.Series): 
    def __init__(self, values, forward='nearest', backward='nearest', middle='linear'): 
     super().__init__(values) 
     self.forward = forward 
     self.backward = backward 
     self.middle = middle 

    def __setitem__(self, key, value): 
     # Do interpolation 
     super().__setitem__(key, value) 

另一種選擇是創建你自己的類,它使用的底層數據結構進行交互。這個類不會從pd.Series繼承,而是一個對象。

class InterpolatedSeries(object): 
    def __init__(self, values, forward='nearest', backward='nearest', middle='linear'): 
     self.data = values 
     self.forward = forward 
     self.backward = backward 
     self.middle = middle 

    def __getitem__(self, key): 
     values = self.data.__getitem__(key) 
     # Do interpolation 
     return values 

    def __getattribute__(self, key): # maybe __getattr__ if this doesn't work 
     """Return the stored pandas series item if the method or attribute was not found. This allows your to_csv method to work""" 
     try: 
      return super().__getattribute__(key) 
     except AttributeError: 
      pass 
     return self.data.__getattribute__(key) # Call the stored pandas series method if not found. 

    def __dir__(self): 
     """Return the list of attributes. (Most code autocomplete features use this, so this will find your pandas series methods for autocomplete in IDEs). """ 
     values = dir(self.data) 
     return values + super().__dir__() 

上面的可能不是最好的方法,但它確實通過使其更容易訪問後臺熊貓系列方法添加了一些靈活性。

+0

謝謝我不知道爲什麼我想的是比__getitem__更復雜的東西,它很整潔,甚至可以處理series.ix [n]調用,因爲如果n在系列中不可用,大熊貓會回退到__getitem__。但是我認爲你需要將結果的__getitem__包裝在一個插值序列中,指定原始序列,否則你會得到奇怪的結果。 – poulter7

+1

正確。您需要將插值結果包裝到另一個InterpolatedSeries對象中。這樣對象就保留了預期的類。我建議你通過使用構造函數self.__ class __()'使其對繼承友好。 – HashSplat