2017-03-02 2 views
1

Je crée actuellement une classe qui hérite d'un DataFrame de pandas. Je suis intéressé par le développement d'une méthode appelée « new_filter » qui est une exécution colombophile d'une commande dataframe:Renvoyer DataFrame en utilisant le bouton ipywidgets

import pandas as pd 
from ipywidgets import widgets 
from IPython.display import display 
import numpy as np 

class Result(pd.DataFrame): 

@property 
def _constructor(self): 
    return Result 

def _filter_done(self, c): 
    self._column_name = self._filter_dd.value 
    self._expression = self._filter_txt.value 
    return self[eval('self.'+ self._column_name +' '+self._expression)] 

def new_filter(self): 
    self._filter_dd = widgets.Dropdown(options=list(self.columns), 
              description='Column:') 
    self._filter_txt = widgets.Text(description='Expr:') 
    self._filter_button = widgets.Button(description = 'Done') 
    self._filter_box = widgets.VBox([self._filter_dd, self._filter_txt, self._filter_button]) 
    display(self._filter_box) 
    self._filter_button.on_click(self._filter_done) 

Après avoir créé un objet comme:

test = Result(np.random.randn(3,4), columns=['A','B','C','D']) #just an example 
test_2 = test.new_filter() 

Ensuite, par exemple: Widget Output

Ce que je veux, c'est que 'test_2' soit un objet de la classe 'Result'. Y a-t-il une solution à cela?

Répondre

1

D'abord, vous devrez retourner quelque chose dans la fonction new_filter. Deuxièmement, si vous voulez que le même objet soit modifié, c'est un peu dur je pense. Une chose que vous pouvez faire est d'avoir un objet qui a un trait qui peut être mis à jour dans _filter_done.

Voici un petit exemple de la façon dont vous pouvez le faire:

import pandas as pd 
from ipywidgets import widgets 
from IPython.display import display 
import numpy as np 

class Result(pd.DataFrame): 
    @property 
    def _constructor(self): 
     return Result 

    def _filter_done(self, obj, c): 
     ## obj is the obejct to be modified. 
     ## Updating its data attribute to have the filtered data. 
     self._column_name = self._filter_dd.value 
     self._expression = self._filter_txt.value 
     obj.data = self[eval('self.'+ self._column_name +' '+self._expression)] 

    def new_filter(self): 
     self._filter_dd = widgets.Dropdown(options=list(self.columns), 
              description='Column:') 
     self._filter_txt = widgets.Text(description='Expr:') 
     self._filter_button = widgets.Button(description = 'Done') 
     self._filter_box = widgets.VBox([self._filter_dd, self._filter_txt, self._filter_button]) 
     display(self._filter_box) 

     result_obj = FilterResult() 
     self._filter_button.on_click(lambda arg: self._filter_done(result_obj, arg)) 
     return result_obj 

from traitlets import HasTraits 
from traittypes import DataFrame 

class FilterResult(HasTraits): 
    data = DataFrame() 

Avec le même code exemple que dans votre question, à savoir,

test = Result(np.random.randn(3,4), columns=['A', 'B', 'C','D']) #just an example 
test_2 = test.new_filter() 

Vous pouvez voir que chaque fois que vous cliquez sur terminé, le dataframe mis à jour est en test_2.data.