使用JupyterLab(Jupyter Notebook)分析数据时,一遍又一遍地重新运行同一单元格(每次稍微修改参数)的代码是非常低效的。尽管如此我还是会这么做,例如为函数选择不同的值,为分析选择不同的日期范围,甚至调整图表的主题。这不仅效率低下,而且令人沮丧,破坏了探索性数据分析的流程。
解决问题的理想方案是使用交互式控件来更改输入,而无需重新运行代码。幸运的是已经有人创造了解决问题的工具。在本文中,我们将学习如何使用Ipywidgets,使用短短几行代码来构建交互式控件。这个库能够将Jupyter Notebook从静态文档转变为交互式仪表盘(Interactive Dashboard),大幅提升数据分析的效率。
安装和配置ipywidgets
先用pip安装ipywidgets: pip install ipywidgets
安装完成后在Jupyter Notebook中激活:
jupyter nbextension enable --py widgetsnbextension
如果使用Jupyterlab,运行以下代码:
jupyter labextension install @jupyter-widgets/jupyterlab-manager
在Notebook中导入并使用ipywidgets:
import ipywidgets as widgets
from ipywidgets import interact, interact_manual
交互式控件入门
假设我们有一个数据框(dataframe),包含Medium文章的统计信息:
如何查看总阅读次数超过1000的文章?
df.loc[df['reads'] > 1000]
如果要显示点赞超过500的文章,必须编写一行新的代码:
df.loc[df['claps'] > 500]
如果不用编写更多代码就可以快速更改这些参数,那不是很好吗?尝试ipywidgets:
@interact
def show_articles_more_than(column='claps', x=5000):return df.loc[df[column] > x]
使用@interact装饰函数,IPywidgets自动创建了一个文本框和滑块控件,它们监控函数的输入,当输入改变时自动重新运行函数并更新结果。现在我们可以使用控件对数据进行分段,而无需反复修改参数。
是否已经注意到一些问题:x可能会变为负数,或者没有输入正确的字段名称。我们可以通过为函数参数提供特定的参数来解决这些问题:
@interact
def show_articles_more_than(column=['claps', 'views', 'fans', 'reads'], x=(10, 100000, 10)):return df.loc[df[column] > x]
运行上面代码后获得了包含字段名称的下拉框,以及一个限制数据范围的滑块。
我们可以用@interact装饰器为任何函数创建交互式控件。例如,想要快速浏览目录中的很多图片:
import os
from IPython.display import Image@interact
def show_images(file=os.listdir('images/')): display(Image(fdir+file))
现在我们可以快速浏览所有图像,而无需重新运行单元。如果你正在构建卷积神经网络并想检查分类错误的图像,这将会非常有用。
交互式控件在探索数据方面的潜力是无限的。另一个简单的示例是检查数据框中两个变量之间的相关性:
用交互式控件控制图表
交互式控件对于数据可视化特别有用,尝试用@interact装饰绘图函数:
import cufflinks as cf@interact
def scatter_plot(x=list(df.select_dtypes('number').columns), y=list(df.select_dtypes('number').columns)[1:],theme=list(cf.themes.THEMES.keys()), colorscale=list(cf.colors._scales_names.keys())):df.iplot(kind='scatter', x=x, y=y, mode='markers', xTitle=x.title(), yTitle=y.title(), text='title',title=f'{y.title()} vs {x.title()}',theme=theme, colorscale=colorscale)
你可能已经注意到图片的更新速度有些慢,在这种情况下可以使用@interact_manual添加按钮,这意味着仅在按下按钮时才会更新图表,这对于需要一段时间才能返回输出的函数很有用。
使用更多交互式控件
我们可以自己创建控件对象并在interact函数中使用它们。我最喜欢的控件之一是DatePicker,假设有一个函数stats_for_article_published_between,接收开始日期和结束日期,然后计算它们之间发布的所有文章的统计信息。
# Create interactive version of function with DatePickers
interact(stats_for_article_published_between,start_date=widgets.DatePicker(value=pd.to_datetime('2018-01-01')),end_date=widgets.DatePicker(value=pd.to_datetime('2019-01-01')))
也可以使用相同的DataPicker控件创建一个函数,绘制直到某个日期为止某变量的累计总数。
如果要使一个控件的选项依赖于另一个控件的值,使用observe函数。这里我们更改图像浏览器函数以选择目录和图像,要展示的图像列表将根据选择的目录自动更新。
# Create widgets
directory = widgets.Dropdown(options=['images', 'nature', 'assorted'])
images = widgets.Dropdown(options=os.listdir(directory.value))# Updates the image options based on directory value
def update_images(*args):images.options = os.listdir(directory.value)# Tie the image options to directory value
directory.observe(update_images, 'value')# Show the images
def show_images(fdir, file):display(Image(f'{fdir}/{file}'))_ = interact(show_images, fdir=directory, file=images)
如何重用控件
如果想在单元格之间重用控件,只需要将它们分配给interact函数的输出即可。
def show_stats_by_tag(tag):return(df.groupby(f'<tag>{tag}').describe()[['views', 'reads']])stats = interact(show_stats_by_tag,tag=widgets.Dropdown(options=['Towards Data Science', 'Education', 'Machine Learning', 'Python', 'Data Science']))
如果要重用该stats控件,只需在另一个单元格中调用stats.widget即可。
上述方法可以在Notebook上反复使用相同的控件。然而请注意,由于这些控件彼此绑定,更新一个单元格中的值将自动更新使用相同控件的另一个单元格的值。
结论
Jupyter Notebook在探索数据和建模方面非常有用,然而它本身的功能不够丰富。使用交互式控件等工具,可以令Notebook栩栩如生,并显著提升数据科学家的工作效率。本文中我们仅仅介绍了Ipywidgets的入门功能,如果想要玩转交互式控件,请浏览官网文档:Ipywidgets文档。
喜欢我们的文章就点赞和收藏吧,我们将继续创作数据科学和量化交易的精品内容。
蜂鸟数据:开源金融数据接口,一个API连接世界金融市场。
蜂鸟数据团队由业界顶尖的数据工程师,数据科学家和宽客组成,我们正努力构建一个强大的金融数据库,并提供API接口,目标是令金融数据开源化和平民化。
浏览并测试我们接口吧,目前覆盖股票,外汇,商品期货,数字货币和宏观经济领域,包括实时报价(tick)和历史数据(分钟),提供REST API和Websocket两种接入方式,能够满足金融分析师,量化交易和理财app的需求。
蜂鸟数据API接口文档
登录蜂鸟官网,注册免费获取API密钥