简体   繁体   English

Jupyter Notebook + iPython 小部件 - 小部件的动态数量

[英]Jupyter Notebook + iPython Widgets - Dynamic Number of Widgets

I'm working on a script that will eventually allow for data exploration using ipywidgets.我正在编写一个脚本,最终将允许使用 ipywidgets 进行数据探索。 I've made some parts work for a dynamic number of columns someone may be interested in filtering on, but implementing the interact function in a dynamic manner is proving to be difficult.我已经为某些人可能有兴趣过滤的动态数量的列做了一些工作,但事实证明以动态方式实现交互功能很困难。 Sample code below that I've been running in Jupyter:下面是我在 Jupyter 中运行的示例代码:

import ipywidgets as widgets
from ipywidgets import interact
import pandas as pd

df = pd.read_csv('https://raw.githubusercontent.com/yankev/testing/master/datasets/nycflights.csv')
df = df.drop(df.columns[[0]], axis=1)

filter_cols = list(['origin','dest','carrier']) #list N columns we want to filter on
filter_df = df[filter_cols] #pull selected N columns from dataframe
filter_df.drop_duplicates(inplace=True) #remove duplicates

#loop through columns and create variables/widgets
for idx, val in enumerate(filter_cols):
    #creates N variables (filter0, filter1, filter2) with unique values for each column with an All option
    globals()['filter{}'.format(idx)] = ['All']+sorted(filter_df[val].unique().tolist())

    #creates N widgets (widget0, widget1, widget2) for interact function below
    globals()['widget{}'.format(idx)] = widgets.SelectMultiple(
        options=globals()['filter{}'.format(idx)],
        value=['All'],
        description=val,
        disabled=False
    )

#looking to make this function dynamic based on the number of columns we want to filter by
#filters down source dataframe based on widget value selections
def viewer(a, b, c = list()):
    #if widget selection is 'All', pass the full filter list, else filter only to what is selected in the widget
    return df[df['origin'].isin(filter0 if a==('All',) else a)
              & df['dest'].isin(filter1 if b==('All',) else b) 
              & df['carrier'].isin(filter2 if c==('All',) else c)].shape[0]

#displays N filters
#returns record count for filter combination
interact(viewer, a=widget0, b=widget1, c=widget2)

The second half of the code, after the loop, is what I'd like to make dynamic.代码的后半部分,在循环之后,是我想要动态化的。 As it stands now, I'd have to change the column name callouts and add/remove code for any additional filters.就目前而言,我必须更改列名称标注并添加/删除任何其他过滤器的代码。 It would be nice to limit the amount of manipulation to a few points in the script.将操作量限制在脚本中的几个点会很好。

Any suggestions are much appreciated.任何建议都非常感谢。 Thanks!谢谢!

I don't quite follow your code in detail, but in general, it is possible to display and interact with a dynamic number of widgets by using keyword arguments:我不太详细地遵循您的代码,但总的来说,可以使用关键字参数显示动态数量的小部件并与之交互:

n_widgets = 3
widget_args = {"widget{}".format(i): widgets.IntSlider() for i in range(n_widgets)}

def viewer(**args):
   print([v for v in args.values])

interact(viewer, **widget_args)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM