使用ipywidgets按钮返回DataFrame

时间:2017-03-02 18:15:14

标签: python python-3.x pandas ipython-notebook ipywidgets

我目前正在创建一个从pandas继承DataFrame的Class。我有兴趣开发一种名为' new_filter'这是一个更精彩的DataFrame命令执行:

$ xmllint --schematron sample-schematron.schema.xml sample-schematron.xml
sample-schematron.schema.xml:11: element rule: Schemas parser error : Failed to compile context expression Person[@Title='Mr']
Schematron schema sample-schematron.schema.xml failed to compile

$ xmllint --version
xmllint: using libxml version 20706
   compiled with: Threads Tree Output Push Reader Patterns Writer SAXv1 FTP HTTP DTDValid HTML Legacy C14N Catalog XPath XPointer XInclude Iconv ISO8859X Unicode Regexps Automata Expr Schemas Schematron Modules Debug Zlib

创建像:

之类的对象
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)

然后,例如: Widget Output

我想要的是' test_2'成为'结果'的对象类。这有什么解决方案吗?

1 个答案:

答案 0 :(得分:1)

首先,您必须在函数new_filter中返回一些内容。其次,如果你想要修改同一个对象,我认为这有点难。你可以做的一件事就是让一个具有特征的对象可以在_filter_done中更新。

以下是一个如何做到这一点的小例子:

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()

使用与您的问题相同的示例代码,即

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

您可以看到,点击“完成”后,更新的dataframe位于test_2.data