动态数据交换 python_如何用 Python 和 Streamlit 做交互式数据分析产品?

「本文参与少数派 2019 年度征文 + 效率有心得」

不用学前端编程,你就能用 Python 简单高效写出漂亮的交互式 Web 应用,将你的数据分析成果立即展示给团队和客户。

痛点

从我开始折腾数据分析工具的那一天,就没有想明白一件事儿 —— 为什么我打算把数据分析的成果做成一个应用,这么难?

其实我需要的核心功能,无非是在网页上接收用户输入,然后做分析处理,把分析结果反馈给用户,完事儿。

可是这谈何容易?

很多人都会笑着告诉你,这得学前端编程, HTML + Javascript 了解一下吧!

什么?你还需要在后台做数据分析?那你就得学 Web 框架了。

你说喜欢 Python ?那就学个 Django 或者 Flask 好了。

我也不是没有看过 Django 和 Flask 的教程,还曾经付费学习过。光是配置环境,就得循序渐进学一堆东西。作为学习的中间成果,我还写了这篇《如何用 Python 做 Web 开发?——Django 环境配置》分享给你。

问题是我在学习中,提不起真正的兴趣。

因为教程里讲的那些功能,我根本不关心。

核心的功能,我早已实现了。我只是希望把输入输出弄成网页形式,方便用户来用。

我为什么要理解那么多的概念?为什么一定要跟那么繁重的数据库操作打交道?为什么几乎所有的样例,都要教我如何做一个 blog ?

我要是想用 blog ,可以直接注册一个免费的啊!难道我要自己开发?

你的教程为什么不干脆教我怎么把数据科学的分析结果,利用这些技术快速变成一个产品?

但是人家写书和做教程的人,就是不疾不徐,坚持一定要教会你,如何做一个 blog 出来……

我仿佛看见达芬奇的老师教学生画鸡蛋一样。

我相信,这绝不仅仅是我一个人的痛点。

我们都希望尽快把数据分析结果,或是其他的交互功能发布出来,和用户交流。但是因为缺乏这样的简单 Web 包裹,我们不得不每次都给别人展示一个包含了代码的 Jupyter Notebook 。

那些不懂编程的用户,看到代码,就会觉得不适。再看到改变一个输入都需要编程(其实就是改语句中的一个赋值),立刻就决定不玩儿了。

万万没想到,这个痛点,如此容易就解决了。

尝试

我用纯 Python 脚本写了个 Web 应用。

我编写的程序里,没有一丝半毫的 Web 框架,Javascript,甚至是 HTML 。

这玩意儿能用吗?

你自己来试试看。

请你打开浏览器,输入以下链接:

你会看到下面的初始化界面。

初始化完毕之后,页面会分成左右两栏。左面是两个下拉候选框,分别让你指定需要分析的数据范围。

上面一个,是事件类型;

下面一个,是事件发生归属地。

只不过,当时我们更注重的,是用循环神经网络搭建了一个严重拥堵事件预测模型。

而今天,我们是要进行探索性数据分析,也就是根据我们感兴趣的目标,对数据进行整理操作,然后可视化显示。

选定之后,你会看到右侧提示两个信息:

你筛选之后,数据框包含行数;

在层叠地图上的可视化结果。

怎么样?

麻雀虽小,五脏俱全。

虽然咱们这个 Web 应用很简单,不过交互分析该有的功能和流程,基本上都涵盖了。

你可能会问:

王老师,编这么一个应用出来,不简单吧?

学完这篇教程,你就能自己开发出这样一个应用来。

幕后

我把这个应用的全部源代码,都为你存储到了 Github 上。请你访问这个网址获取。

可以看到,一共包含了 4 个文件。

有意思的是,其中 3 个,包括:

Procfile

setup.sh

requirements.txt

都只是部署到远程服务器时,需要用到的配置文件而已。

这些文件的具体使用方法,咱们后面会说明。

也就是说,只有最后一个 helloworld.py 是主角,它包含了实现咱们全部交互式数据分析功能的 Python 脚本文件。

这代码,少说也得有几百行吧?

别担心,打开来看看:

上面这张截图,就已经包含了实现交互数据分析功能的全部代码。

神奇吧?

解读

这么短的代码,为什么能有如此强大的功能?

这是因为它背后使用的一个软件包,叫做 streamlit 。

下面我通过实际操作,带你初步领略一下 streamlit 的威力。

首先请你安装 Anaconda ,这个请参考我为你做的视频教程《如何安装 Python 运行环境 Anaconda?》

然后,你需要打开终端,执行:

pip install streamlit

你可以创建一个新目录。然后在目录下新建一个 helloworld.py 文件,并且用任意编辑器打开它。

我这里用 Visual Studio Code 编辑器,来编辑和制作 Python 脚本文件。

然后,回到终端下,执行:

streamlit run helloworld.py

如果一切顺利,你就会看到如下图的提示。

一般来说,你的浏览器会自动开启,并且访问上图中红色标识出的网址。

如果浏览器没有自动开启,你手动开启一个,并且输入上述网址即可。

为了演示方便,我这里把 Visual Studio Code 编辑器缩小到屏幕左侧半部;右边放置 Chrome 浏览器,来显示 Web 应用效果。

我们可以开始尝试了。

首先在 helloworld.py 中输入这些内容:

import streamlit as st

import numpy as np

import pandas as pd

st.title("my first app")

输入完之后,你不需要去找什么执行按钮。只需要保存一下你对 helloworld.py 文件的修改即可。

之后你会立即在右侧看到 Web 应用的运行效果。

这里前几行语句,只是引入了几个软件包,然后设置了一下标题。

下面我们尝试点儿好玩儿的。

x = st.slider("x")

y = x + 3

y

这时候网页上出现了滑动条,告诉你这是 x 的取值。

我们定义了一个式子,让 y 总比 x 大 3 ,并且显示 y 。

你可以试试,在滑动条拖拽 x 的效果。

Jan-14-2020-18-39-15.gif

y 值紧随你的拖动变化,对吧?

从这个简单的例子里,你可以看到 streamlit 响应用户的输入和输出是多么方便。

而且应用上的控件一直运行。你输入的变化,会实时带来输出的变化。

下面我们还是步入正题吧。先注释掉刚才这三条语句,免得碍事儿。

# x = st.slider("x")

# y = x + 3

# y

我们定义一个函数:

@st.cache

def load_data():

df = pd.read_csv("data.csv")

df = df

df.columns = ['event_type', 'time', 'county', 'lat', 'lon']

return df

如果你学过那篇《如何用 Python 和 Pandas 分析犯罪记录开放数据?》,里面的其他语句你应该都认得。无非就是 Pandas 读入我们的 CSV 数据之后,取其中的 5 个列,包括:

EVENT_TYPE : 事件类型;

CREATE_TIME: 事件创建时间;

COUNTY:事件发生位置所在郡名称;

LAT:事件发生位置的纬度;

LON:事件发生位置的经度

然后,我们把这几个列分别用小写的名称来命名。

值得一提的,是 @st.cache ,这是一个新玩意儿。

它是什么呢?

这在 Python 里面,叫做装饰器(decorator) 。其实这里没有什么魔法,它只是 streamlit 软件包里,一个预先定义的函数。

只不过这样写,相当于是你在自己的 load_data() 函数之外,又包裹了一个 st.cache() 函数的功能。每次执行的时候, st.cache() 都会参与进来。

st.cache() 这个函数做什么用呢?

那作用可太大了。

因为你每次更新代码,或者用户更新输入,整个儿 Python 脚本都相当于被重新执行了一遍。

而 st.cache() 装饰器可以告诉 Python :

查查看,我包裹的这个函数,内容或者输入改过没有?如果没有,就用已存储的上次调用结果好了,别再费事重新执行一遍了。

我们这里是从一个外部文件读入数据。就这样一个 300MB 的文件,每次读起来也得花上近 10 秒钟。更别说是那些上 GB 规模,甚至更大的文件了。

所以,如果 Streamlit 能够帮助我们跳过一些无意义的重复操作,将节省大量的用户等待时长。

不过这一步,你也看到了,输出没有变化。

因为我们什么也没有输出啊。

下面我们让 Python 实际读数据,并且把读后的数据框前 5 行用列表形式(st.table())展示给用户。

这一读数据不要紧,右上角会出现一个小人儿,做各种健身运动。

这就是告诉我们,程序在忙着呢。

忙完之后,这是结果:

下面我们要让程序给用户选项,首先是选择观察哪一种事件类型。

event_list = df["event_type"].unique()

event_type = st.sidebar.selectbox(

"Which kind of event do you want to explore?",

event_list

)

解释一下,第一句是在 event_type 里面寻找全部事件类型列表。

下面一段,采用了 st.sidebar.selectbox() 构造了一个左边栏里的下拉选择框。里面两个参数,第一个是显示给用户的提示语句,第二个,是选择列表内容。

问题是,我们存储了之后,好像什么也没有发生啊。

没关系,看到上图里面红色标出的这个箭头没有?

点击它,选项就出现了。

照葫芦画瓢,我们顺便把事件发生所在郡的下拉选择框一并做出来。

county_list = df["county"].unique()

county_name = st.sidebar.selectbox(

"Which county?",

county_list

)

这是效果:

然后,我们根据用户的输入做出反应,提示给用户经过他的选择,现在符合要求的行数还有多少。

part_df = df[(df["event_type"]==event_type) & (df['county']==county_name)]

st.write(f"根据你的筛选,数据包含{len(part_df)}行")

第一句里面用了个联合筛选,必须同时满足两个条件的数据,才会被保留在结果 part_df 中。

然后,我们把一个格式化后的字符串,用 st.write() 直接输出在网页上。

运行结果如下图所示。

Jan-14-2020-19-04-42.gif

好了,下面可能是你最关心的一刻了。

老师,别卖关子了,那张标示了事件位置的叠层地图怎么画啊?一共都没有多少行语句,你都讲了这么多了,怎么还没讲到?

请你输入下面这一行语句:

st.map(part_df)

然后保存。你就会看到下面的效果了。

是不是很惊讶?

我第一次用的时候,也是这感觉。

在 HackNTX 2018 编程马拉松竞赛中,我曾经找不同的编程高手学了若干种地理信息可视化的工具。每一种都得花上很多时间学习演练。

没想到,短短一年的时间,这样的功能居然可以用一行代码就实现了。

还是集成在 Web 应用里,可以发布给全球用户与合作者,进行展示。

不是我不明白,这世界变化快啊。

部署

我知道,你又开始着急了。

老师,这么好的东西,我可不想在本地一个人玩儿。我也想把结果发布到网络上,让别人看到我的成果。快告诉我怎么办!

别急。

咱们部署( deploy )一下它就行。

虽然你写了半天,只是 Python 脚本。但是 Streamlit 已经把它转换成了一个动态的 Web 应用。

所以,只要是常见的 Web 应用发布平台,理论上你都可以用来部署你的交互式数据分析作品。

这些平台,常见的包括:

EC2

Glitch

Heroku

这列表列下去就太多了。咱们这里只介绍 Heroku ,也就是前文给你展示的,样例使用的部署平台。

这东西的好处,就是基础款免费。

对咱们今天的教程来说,基础款就足够了。

你需要先到 Heroku 平台注册一个账号。

我这里起的名字,叫做 helloworld-streamlit 。

你可以根据自己的喜好,起名称。

之后我们就要部署了。

部署的步骤,在上图中,你可以参考。

注意,上图中,右上角的 Open App 按钮,就是你的应用链接地址,你可以把它记下来。

首先你需要准备一些配置文件。

全部的配置文件,我都给你展示在了前文介绍过的这个 github 项目中,你可以下载回来复用。

这里需要说明的是,几个不同配置文件的用途。

setup.sh 做一些初始设置,设定一些参数。

注意你将来用的时候,需要把其中标红的部分,替换成自己注册 heroku 时候的邮箱。

requirements.txt 告诉机器,需要安装哪些 Python 依赖包。

显然,教程这里需要的依赖包不多。

Procfile 是远端服务器上, Web 应用启动的时候,需要调用的脚本。其实里面只有一行。

请你下载,或者自行编辑上述 3 个文件后,与你的 Python 文件放在一个文件夹下面。

之后,请你到这里下载 heroku cli package。

下载后,根据提示安装即可。

进入终端。用 cd 命令切换到你的工作文件夹,也就是包含了你的 Python 脚本的目录。

输入:

heroku login

因为你已经在 setup.sh 中指定了自己的邮箱,所以这里会尝试直接用它来登录。

这时按任意键,会跳出一个浏览器窗口。

在浏览器中,点击确认即可登录。

看到上面的提示,证明登录成功了。

下面我们来设置 git ,这是推送我们文件和更新改动的途径。

在终端下执行:

git init

之后设置一下与远端的 heroku 服务器的连接:

heroku git:remote -a helloworld-streamlit

若是看到下图,证明成功了:

然后执行:

git add .

git commit -m "init"

再执行:

git push heroku master

这样就可以把全部内容推送到 heroku 了。

推送的第一步,是上传文件。

Heroku 发现咱们推送的是一个 Python App ,所以自动执行许多安装设置工作。

这些安装和配置做完后,会出现下面这样的提示。

到这里,你的 Web 应用部署就搞定了。

回到浏览器里,用下图中标红的这个按钮开启你自己的应用吧。

怎么样?

很有成就感吧?

思考

尝试过之后,你应该不难发现,Streamlit 给你带来了什么。

如果你学过 Javascript 和 Flask, Django 等 Web 应用开发技术,Streamlit 可以加快你的 Web 应用开发与测试进程。

如果你还没有学过上述技术, Streamlit 就可以给你赋能,让你一下子有了把数据分析结果变成产品的能力。

给你讲点儿更激进的。

有人已经希望能用它替代掉 Flask 用于产品发布了。

还有人说,将来写技术文档,也应该充分使用 Streamlit 。

甚至,还把它比作了数据科学界的 iPhone 。

这里,它是借喻 iPhone 开启智能手机时代,说明 Streamlit 的划时代性。

我不希望你也变得如此激进。

因为这里提到的每一种功用,现在还都有非常专业的工具做的更好,而且新的工具也在不断涌现。

例如说,我们在多个教程中一直使用 Jupyter Notebook 。

现在凭借 Voila 扩展的加持,你也可以很轻松地把 Jupyter Notebook 变成 Web app ,而且可以免费运行在 mybinder 上面。

但是,你可以看到,一个新的工具,以一种简单,而不是更繁复的办法,解决一个功能痛点,是一件多么令人欣喜的事儿。

看了这篇文章,可能会给你一种误解,似乎 JavaScript 为代表的前端编程技术,再也不需要学了。

其实不是这样的。

可以想象,开发门槛降低以后,将来会有更多的人使用 Python 来做 Web 应用。

用 Streamlit 这样的方法,他们只是开发出了一个原型。

要是想打造精品,就必须精细调控很多细节。

这时候, Javascript 是绕不过去的。

如果你精通 Javascript ,那你潜在的合作对象一下子就多了起来,你掌握的这门技术,也就有了更大的价值。

还记得吗?我不止一次给你强调过,协作网络更重要。忘了的话,记得复习《学 Python ,能提升你的竞争力吗?》。

这就好像印刷术的发明,不是让会写字这件事儿变得失去价值,而是全社会都增大了对好作品的渴求。深刻的思考,加上有效的文字表达,会让你生存得更好。

当然,如果你不希望精通写作技艺,只是想做一个抄书匠糊口。那么印刷术就可能会替代你的工作,结果就不那么美妙了。

小结

本文我为你介绍了 Streamlit ,它可以让你用 Python 脚本编写简洁实用的交互式 Web 应用。

通过学习本文,希望你掌握了以下知识点:

现在你有了一种选择,仅用纯 Python 做一个完整的交互式数据分析产品出来;

如何在读取数据等常用重复操作中,使用 st.cache 装饰器提升速度与效率;

如何使用滑动条、下拉框等基本组件;

如何在网页上输出文字、表格和图像;

如何把你本地构建和测试后的 Web 应用部署到 Heroku 上,以发布给你的合作者与客户。

咱们是以数据分析和可视化为例,进行了讲解。而且为了讲解的清晰,我们只介绍了 Streamlit 可实现功能的一小部分。但请注意,即便是目前, Streamlit 能帮你达成的目标,也远远不止于此。

希望你能够举一反三,用 Streamlit 做出令人惊艳的作品。也欢迎你把作品的链接在留言区分享给咱们的同学。

祝编程愉快!

读过本文,如果觉得有收获,请点赞。

要读更多的文章,微信关注我的公众号 “玉树芝兰”(nkwangshuyi)。别忘了加星标,以免错过新推送提示。

如果本文对你身边的亲友有帮助,也欢迎你把本文通过微博或朋友圈分享给他们。

延伸阅读

你可能也会对以下话题感兴趣。点击链接就可以查看。

题图:Photo by Luke Chesser on Unsplash

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/335986.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【技术解决方案】GitHub本地仓库管理与远程仓库管理

本地仓库管理 设置用户名 git config --global user.name CnYiXiaoNaiHe 设置邮箱 git config --global user.email 1969118063qq.com 该设置在Github仓库主页显示谁提交了该文件 创建新文件夹,打开,然后执行 git init 把文件从工作区提交到暂存…

jboss war包放哪_如何将JBoss HR Employee Rewards项目放入云端

jboss war包放哪我们一直在讨论为什么应用程序开发人员在App Dev Cloud Stack系列中不能再忽略其堆栈了。 我们从头到尾讨论了各个层次,但尚未为您提供除Red Hat Container Development Kit(CDK)之外的任何应用程序开发工具。 到目前为止&am…

hotspot 垃圾收集器_HotSpot增量Java垃圾收集器

hotspot 垃圾收集器在我最近的博客文章“ 确定活动的HotSpot垃圾收集器”中 ,我描述了可用于确定HotSpot JVM (Java进程)正在使用的垃圾收集器(当从命令行参数(标志)中变得不明显时)的不同方法。…

python聚类分析成绩反思_机器学习python实践——二分K-means聚类

说这算法之前的话,前期的准备工作,请看我前面的博客。上一篇,我说到了K-means聚类算法,但是有很多的不足,有很多能够改进的地方,例如,怎样使得聚类效果达到全局最优(可能的最好结果)呢&#xff…

apache spark_如何将自定义数据源集成到Apache Spark中

apache spark如今,流数据是一个热门话题,而Apache Spark是出色的流框架。 在此博客文章中,我将向您展示如何将自定义数据源集成到Spark中。 Spark Streaming使我们能够从各种来源流式传输,同时使用相同的简洁API访问数据流&#…

python采用函数编程模式_浅谈Python 函数式编程

匿名函数lambda表达式什么是匿名函数?匿名函数,顾名思义就是没有名字的函数,在程序中不用使用 def 进行定义,可以直接使用 lambda 关键字编写简单的代码逻辑。lambda 本质上是一个函数对象,可以将其赋值给另一个变量&a…

【安卓开发 】Android初级开发(一)控件通用属性

控件通用属性 match_parent 是指和父容器宽高相等的值,其他的同理可证。 android:layout_marginTop"XXXXXXdp" 距离顶部的距离 Android TextView属性详解 该控件相关属性 Android EditText属性大全 相关属性查看地址 事件监听处理 package com.examp…

dynamodb java_使用Java将项目插入DynamoDB表

dynamodb java在上一篇文章中,我们学习了如何使用Java创建DynamoDB表。 下一步是将项目插入到先前创建的DynamoDB表中。 请记住,对于插入操作,最基本的步骤是指定主键。 对于表用户,主键是属性电子邮件。 您可以根据需要添加任意…

成都python数据分析师职业技能_数据分析师需要什么技能,数据分析行业都有什么职业?...

就目前而言,很多人看到了数据分析行业的光明前景,于是就想进入数据分析的行业中,但是,想成为一名合格的数据分析师,需要掌握很多的技能,那么一名合格的数据分析师需要掌握哪些技能呢?现在的数据…

【安卓开发 】Android初级开发(零)各种布局

线性布局的重要属性 (LinearLayout) 相关属性链接 layout_width 和 layout_height是布局器相对于外部构件的一个宽高距离。 layout_margin是指与外部控件的整个边缘距离。 padding是指与控件的内边距离 android:orientation 方向作用于整个布局中的所有控件 android:layo…

jboss fuse 教程_JBoss Fuse:使用JEXL的动态蓝图文件

jboss fuse 教程在本文中,我将展示如何在Apache Aries Blueprint xml文件中添加一些内联脚本。 我不一定会称其为最佳实践,但我一直有这样的想法:这种能力可能有用。 可能当我被迫使用xml来模拟命令式编程结构(例如使用Apache An…

认证令牌_Java应用程序的令牌认证

认证令牌建筑物身份管理,包括身份验证和授权? 尝试Stormpath! 我们的REST API和强大的Java SDK支持可以消除您的安全风险,并且可以在几分钟内实现。 注册 ,再也不会建立auth了! 2016年5月12日更新&#xf…

java package报错_Java基础知识总结 - 超详细篇(上)

1,JDK:Java Development Kit,java的开发和运行环境,java的开发工具和jre。2,JRE:Java Runtime Environment,java程序的运行环境,java运行的所需的类库JVM(java虚拟机)。3&#xff0c…

【安卓开发 】Android初级开发(二)Activity启动模式

Activity页面跳转在业务逻辑页面添加以下代码 //跳转到下一个activityIntent intent new Intent(this,MainActivity2.class);startActivity(intent); Activity四种启动模式 具体链接

weblogic 建立websocket连接报404_基于 Serverless 与 Websocket 的聊天工具实现

传统业务实现 Websocket 并不难,然而函数计算基本上都是事件驱动,不支持长链接操作。如果将函数计算与 API 网关结合,是否可以有 Websocket 的实现方案呢?API 网关触发器实现 WebsocketWebSocket 协议是基于 TCP 的一种新的网络协…

java的默认值规则_Java 8:默认方法解析规则

java的默认值规则随着Java 8中默认方法的引入,一个类现在可以从多个位置(例如另一个类或接口)继承相同的方法。 在这种情况下,可以使用以下规则来确定选择哪种方法: 类或超类方法声明始终优先于默认方法 否则&#x…

【Android OpenGL ES 开发 (五)】纹理相关(二)

纹理放大和缩小的过滤参数 1.使用线性插值效果最佳 2.通过修改 float maxscale 4.0f //放大 float minscale 0.5f //缩小 vertices[0].mPosition[0]0.5f * maxscale; //x vertices[0].mPosition[1]0.5f * maxscale; //y 实现模糊效果 1.利用显卡的并行计算的强大功能对…

python与sqlite3_sqlite3与python2.5,pysqlite和apsw有什么区别

我想知道python2.5,pysqlite和apsw的sqlite3之间的区别?当我尝试使用python2.5在windows vista上安装pysqlite时,我有一个颠簸的运行,请参阅以下内容:>从http://sqlite.org/download.html下载sqlite并将它们解压缩到windows / system32文件夹并将sqli…

monolith_将Java EE Monolith雕刻成微服务

monolith在介绍了为什么微服务应该由事件驱动的简介博客之后,我想采取一些其他步骤,并在有关博客的同时准备我即将进行的一系列演讲(在jBCNconf和Red Hat Summit上与您见面) 。旧金山 )。 在Twitter christianposta上关…

【H.264/AVC视频编解码技术】第四章【SPS序列参数集】

1.H264码流中重要的组成部分,保存针对整个视频序列的参数,丢失SPS的码流通常无法正常解码。 2.SPS信息的保存位置: 封装格式: FLV======会保存在 Tag中的Video Tag Data 部分,会有AVC VIDEO PACKET结构。SPS就包含在其中。 MP4===== H264裸码流: 保存…