动态数据交换 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
總結
以上是生活随笔為你收集整理的动态数据交换 python_如何用 Python 和 Streamlit 做交互式数据分析产品?的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python哪个方向简单_现在学Pyth
- 下一篇: python聚类分析成绩反思_机器学习p