动态数据交换 python_如何用 Python 和 Streamlit 做交互式数据分析产品?
「本文參與少數(shù)派 2019 年度征文 + 效率有心得」
不用學(xué)前端編程,你就能用 Python 簡(jiǎn)單高效寫出漂亮的交互式 Web 應(yīng)用,將你的數(shù)據(jù)分析成果立即展示給團(tuán)隊(duì)和客戶。
痛點(diǎn)
從我開(kāi)始折騰數(shù)據(jù)分析工具的那一天,就沒(méi)有想明白一件事兒 —— 為什么我打算把數(shù)據(jù)分析的成果做成一個(gè)應(yīng)用,這么難?
其實(shí)我需要的核心功能,無(wú)非是在網(wǎng)頁(yè)上接收用戶輸入,然后做分析處理,把分析結(jié)果反饋給用戶,完事兒。
可是這談何容易?
很多人都會(huì)笑著告訴你,這得學(xué)前端編程, HTML + Javascript 了解一下吧!
什么?你還需要在后臺(tái)做數(shù)據(jù)分析?那你就得學(xué) Web 框架了。
你說(shuō)喜歡 Python ?那就學(xué)個(gè) Django 或者 Flask 好了。
我也不是沒(méi)有看過(guò) Django 和 Flask 的教程,還曾經(jīng)付費(fèi)學(xué)習(xí)過(guò)。光是配置環(huán)境,就得循序漸進(jìn)學(xué)一堆東西。作為學(xué)習(xí)的中間成果,我還寫了這篇《如何用 Python 做 Web 開(kāi)發(fā)?——Django 環(huán)境配置》分享給你。
問(wèn)題是我在學(xué)習(xí)中,提不起真正的興趣。
因?yàn)榻坛汤镏v的那些功能,我根本不關(guān)心。
核心的功能,我早已實(shí)現(xiàn)了。我只是希望把輸入輸出弄成網(wǎng)頁(yè)形式,方便用戶來(lái)用。
我為什么要理解那么多的概念?為什么一定要跟那么繁重的數(shù)據(jù)庫(kù)操作打交道?為什么幾乎所有的樣例,都要教我如何做一個(gè) blog ?
我要是想用 blog ,可以直接注冊(cè)一個(gè)免費(fèi)的啊!難道我要自己開(kāi)發(fā)?
你的教程為什么不干脆教我怎么把數(shù)據(jù)科學(xué)的分析結(jié)果,利用這些技術(shù)快速變成一個(gè)產(chǎn)品?
但是人家寫書和做教程的人,就是不疾不徐,堅(jiān)持一定要教會(huì)你,如何做一個(gè) blog 出來(lái)……
我仿佛看見(jiàn)達(dá)芬奇的老師教學(xué)生畫雞蛋一樣。
我相信,這絕不僅僅是我一個(gè)人的痛點(diǎn)。
我們都希望盡快把數(shù)據(jù)分析結(jié)果,或是其他的交互功能發(fā)布出來(lái),和用戶交流。但是因?yàn)槿狈@樣的簡(jiǎn)單 Web 包裹,我們不得不每次都給別人展示一個(gè)包含了代碼的 Jupyter Notebook 。
那些不懂編程的用戶,看到代碼,就會(huì)覺(jué)得不適。再看到改變一個(gè)輸入都需要編程(其實(shí)就是改語(yǔ)句中的一個(gè)賦值),立刻就決定不玩兒了。
萬(wàn)萬(wàn)沒(méi)想到,這個(gè)痛點(diǎn),如此容易就解決了。
嘗試
我用純 Python 腳本寫了個(gè) Web 應(yīng)用。
我編寫的程序里,沒(méi)有一絲半毫的 Web 框架,Javascript,甚至是 HTML 。
這玩意兒能用嗎?
你自己來(lái)試試看。
請(qǐng)你打開(kāi)瀏覽器,輸入以下鏈接:
你會(huì)看到下面的初始化界面。
初始化完畢之后,頁(yè)面會(huì)分成左右兩欄。左面是兩個(gè)下拉候選框,分別讓你指定需要分析的數(shù)據(jù)范圍。
上面一個(gè),是事件類型;
下面一個(gè),是事件發(fā)生歸屬地。
只不過(guò),當(dāng)時(shí)我們更注重的,是用循環(huán)神經(jīng)網(wǎng)絡(luò)搭建了一個(gè)嚴(yán)重?fù)矶率录A(yù)測(cè)模型。
而今天,我們是要進(jìn)行探索性數(shù)據(jù)分析,也就是根據(jù)我們感興趣的目標(biāo),對(duì)數(shù)據(jù)進(jìn)行整理操作,然后可視化顯示。
選定之后,你會(huì)看到右側(cè)提示兩個(gè)信息:
你篩選之后,數(shù)據(jù)框包含行數(shù);
在層疊地圖上的可視化結(jié)果。
怎么樣?
麻雀雖小,五臟俱全。
雖然咱們這個(gè) Web 應(yīng)用很簡(jiǎn)單,不過(guò)交互分析該有的功能和流程,基本上都涵蓋了。
你可能會(huì)問(wèn):
王老師,編這么一個(gè)應(yīng)用出來(lái),不簡(jiǎn)單吧?
學(xué)完這篇教程,你就能自己開(kāi)發(fā)出這樣一個(gè)應(yīng)用來(lái)。
幕后
我把這個(gè)應(yīng)用的全部源代碼,都為你存儲(chǔ)到了 Github 上。請(qǐng)你訪問(wèn)這個(gè)網(wǎng)址獲取。
可以看到,一共包含了 4 個(gè)文件。
有意思的是,其中 3 個(gè),包括:
Procfile
setup.sh
requirements.txt
都只是部署到遠(yuǎn)程服務(wù)器時(shí),需要用到的配置文件而已。
這些文件的具體使用方法,咱們后面會(huì)說(shuō)明。
也就是說(shuō),只有最后一個(gè) helloworld.py 是主角,它包含了實(shí)現(xiàn)咱們?nèi)拷换ナ綌?shù)據(jù)分析功能的 Python 腳本文件。
這代碼,少說(shuō)也得有幾百行吧?
別擔(dān)心,打開(kāi)來(lái)看看:
上面這張截圖,就已經(jīng)包含了實(shí)現(xiàn)交互數(shù)據(jù)分析功能的全部代碼。
神奇吧?
解讀
這么短的代碼,為什么能有如此強(qiáng)大的功能?
這是因?yàn)樗澈笫褂玫囊粋€(gè)軟件包,叫做 streamlit 。
下面我通過(guò)實(shí)際操作,帶你初步領(lǐng)略一下 streamlit 的威力。
首先請(qǐng)你安裝 Anaconda ,這個(gè)請(qǐng)參考我為你做的視頻教程《如何安裝 Python 運(yùn)行環(huán)境 Anaconda?》
然后,你需要打開(kāi)終端,執(zhí)行:
pip?install?streamlit
你可以創(chuàng)建一個(gè)新目錄。然后在目錄下新建一個(gè) helloworld.py 文件,并且用任意編輯器打開(kāi)它。
我這里用 Visual Studio Code 編輯器,來(lái)編輯和制作 Python 腳本文件。
然后,回到終端下,執(zhí)行:
streamlit?run?helloworld.py
如果一切順利,你就會(huì)看到如下圖的提示。
一般來(lái)說(shuō),你的瀏覽器會(huì)自動(dòng)開(kāi)啟,并且訪問(wèn)上圖中紅色標(biāo)識(shí)出的網(wǎng)址。
如果瀏覽器沒(méi)有自動(dòng)開(kāi)啟,你手動(dòng)開(kāi)啟一個(gè),并且輸入上述網(wǎng)址即可。
為了演示方便,我這里把 Visual Studio Code 編輯器縮小到屏幕左側(cè)半部;右邊放置 Chrome 瀏覽器,來(lái)顯示 Web 應(yīng)用效果。
我們可以開(kāi)始嘗試了。
首先在 helloworld.py 中輸入這些內(nèi)容:
import?streamlit?as?st
import?numpy?as?np
import?pandas?as?pd
st.title("my?first?app")
輸入完之后,你不需要去找什么執(zhí)行按鈕。只需要保存一下你對(duì) helloworld.py 文件的修改即可。
之后你會(huì)立即在右側(cè)看到 Web 應(yīng)用的運(yùn)行效果。
這里前幾行語(yǔ)句,只是引入了幾個(gè)軟件包,然后設(shè)置了一下標(biāo)題。
下面我們嘗試點(diǎn)兒好玩兒的。
x?=?st.slider("x")
y?=?x?+?3
y
這時(shí)候網(wǎng)頁(yè)上出現(xiàn)了滑動(dòng)條,告訴你這是 x 的取值。
我們定義了一個(gè)式子,讓 y 總比 x 大 3 ,并且顯示 y 。
你可以試試,在滑動(dòng)條拖拽 x 的效果。
Jan-14-2020-18-39-15.gif
y 值緊隨你的拖動(dòng)變化,對(duì)吧?
從這個(gè)簡(jiǎn)單的例子里,你可以看到 streamlit 響應(yīng)用戶的輸入和輸出是多么方便。
而且應(yīng)用上的控件一直運(yùn)行。你輸入的變化,會(huì)實(shí)時(shí)帶來(lái)輸出的變化。
下面我們還是步入正題吧。先注釋掉剛才這三條語(yǔ)句,免得礙事兒。
#?x?=?st.slider("x")
#?y?=?x?+?3
#?y
我們定義一個(gè)函數(shù):
@st.cache
def?load_data():
df?=?pd.read_csv("data.csv")
df?=?df
df.columns?=?['event_type',?'time',?'county',?'lat',?'lon']
return?df
如果你學(xué)過(guò)那篇《如何用 Python 和 Pandas 分析犯罪記錄開(kāi)放數(shù)據(jù)?》,里面的其他語(yǔ)句你應(yīng)該都認(rèn)得。無(wú)非就是 Pandas 讀入我們的 CSV 數(shù)據(jù)之后,取其中的 5 個(gè)列,包括:
EVENT_TYPE : 事件類型;
CREATE_TIME: 事件創(chuàng)建時(shí)間;
COUNTY:事件發(fā)生位置所在郡名稱;
LAT:事件發(fā)生位置的緯度;
LON:事件發(fā)生位置的經(jīng)度
然后,我們把這幾個(gè)列分別用小寫的名稱來(lái)命名。
值得一提的,是 @st.cache ,這是一個(gè)新玩意兒。
它是什么呢?
這在 Python 里面,叫做裝飾器(decorator) 。其實(shí)這里沒(méi)有什么魔法,它只是 streamlit 軟件包里,一個(gè)預(yù)先定義的函數(shù)。
只不過(guò)這樣寫,相當(dāng)于是你在自己的 load_data() 函數(shù)之外,又包裹了一個(gè) st.cache() 函數(shù)的功能。每次執(zhí)行的時(shí)候, st.cache() 都會(huì)參與進(jìn)來(lái)。
st.cache() 這個(gè)函數(shù)做什么用呢?
那作用可太大了。
因?yàn)槟忝看胃麓a,或者用戶更新輸入,整個(gè)兒 Python 腳本都相當(dāng)于被重新執(zhí)行了一遍。
而 st.cache() 裝飾器可以告訴 Python :
查查看,我包裹的這個(gè)函數(shù),內(nèi)容或者輸入改過(guò)沒(méi)有?如果沒(méi)有,就用已存儲(chǔ)的上次調(diào)用結(jié)果好了,別再費(fèi)事重新執(zhí)行一遍了。
我們這里是從一個(gè)外部文件讀入數(shù)據(jù)。就這樣一個(gè) 300MB 的文件,每次讀起來(lái)也得花上近 10 秒鐘。更別說(shuō)是那些上 GB 規(guī)模,甚至更大的文件了。
所以,如果 Streamlit 能夠幫助我們跳過(guò)一些無(wú)意義的重復(fù)操作,將節(jié)省大量的用戶等待時(shí)長(zhǎng)。
不過(guò)這一步,你也看到了,輸出沒(méi)有變化。
因?yàn)槲覀兪裁匆矝](méi)有輸出啊。
下面我們讓 Python 實(shí)際讀數(shù)據(jù),并且把讀后的數(shù)據(jù)框前 5 行用列表形式(st.table())展示給用戶。
這一讀數(shù)據(jù)不要緊,右上角會(huì)出現(xiàn)一個(gè)小人兒,做各種健身運(yùn)動(dòng)。
這就是告訴我們,程序在忙著呢。
忙完之后,這是結(jié)果:
下面我們要讓程序給用戶選項(xiàng),首先是選擇觀察哪一種事件類型。
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() 構(gòu)造了一個(gè)左邊欄里的下拉選擇框。里面兩個(gè)參數(shù),第一個(gè)是顯示給用戶的提示語(yǔ)句,第二個(gè),是選擇列表內(nèi)容。
問(wèn)題是,我們存儲(chǔ)了之后,好像什么也沒(méi)有發(fā)生啊。
沒(méi)關(guān)系,看到上圖里面紅色標(biāo)出的這個(gè)箭頭沒(méi)有?
點(diǎn)擊它,選項(xiàng)就出現(xiàn)了。
照葫蘆畫瓢,我們順便把事件發(fā)生所在郡的下拉選擇框一并做出來(lái)。
county_list?=?df["county"].unique()
county_name?=?st.sidebar.selectbox(
"Which?county?",
county_list
)
這是效果:
然后,我們根據(jù)用戶的輸入做出反應(yīng),提示給用戶經(jīng)過(guò)他的選擇,現(xiàn)在符合要求的行數(shù)還有多少。
part_df?=?df[(df["event_type"]==event_type)?&?(df['county']==county_name)]
st.write(f"根據(jù)你的篩選,數(shù)據(jù)包含{len(part_df)}行")
第一句里面用了個(gè)聯(lián)合篩選,必須同時(shí)滿足兩個(gè)條件的數(shù)據(jù),才會(huì)被保留在結(jié)果 part_df 中。
然后,我們把一個(gè)格式化后的字符串,用 st.write() 直接輸出在網(wǎng)頁(yè)上。
運(yùn)行結(jié)果如下圖所示。
Jan-14-2020-19-04-42.gif
好了,下面可能是你最關(guān)心的一刻了。
老師,別賣關(guān)子了,那張標(biāo)示了事件位置的疊層地圖怎么畫啊?一共都沒(méi)有多少行語(yǔ)句,你都講了這么多了,怎么還沒(méi)講到?
請(qǐng)你輸入下面這一行語(yǔ)句:
st.map(part_df)
然后保存。你就會(huì)看到下面的效果了。
是不是很驚訝?
我第一次用的時(shí)候,也是這感覺(jué)。
在 HackNTX 2018 編程馬拉松競(jìng)賽中,我曾經(jīng)找不同的編程高手學(xué)了若干種地理信息可視化的工具。每一種都得花上很多時(shí)間學(xué)習(xí)演練。
沒(méi)想到,短短一年的時(shí)間,這樣的功能居然可以用一行代碼就實(shí)現(xiàn)了。
還是集成在 Web 應(yīng)用里,可以發(fā)布給全球用戶與合作者,進(jìn)行展示。
不是我不明白,這世界變化快啊。
部署
我知道,你又開(kāi)始著急了。
老師,這么好的東西,我可不想在本地一個(gè)人玩兒。我也想把結(jié)果發(fā)布到網(wǎng)絡(luò)上,讓別人看到我的成果。快告訴我怎么辦!
別急。
咱們部署( deploy )一下它就行。
雖然你寫了半天,只是 Python 腳本。但是 Streamlit 已經(jīng)把它轉(zhuǎn)換成了一個(gè)動(dòng)態(tài)的 Web 應(yīng)用。
所以,只要是常見(jiàn)的 Web 應(yīng)用發(fā)布平臺(tái),理論上你都可以用來(lái)部署你的交互式數(shù)據(jù)分析作品。
這些平臺(tái),常見(jiàn)的包括:
EC2
Glitch
Heroku
這列表列下去就太多了。咱們這里只介紹 Heroku ,也就是前文給你展示的,樣例使用的部署平臺(tái)。
這東西的好處,就是基礎(chǔ)款免費(fèi)。
對(duì)咱們今天的教程來(lái)說(shuō),基礎(chǔ)款就足夠了。
你需要先到 Heroku 平臺(tái)注冊(cè)一個(gè)賬號(hào)。
我這里起的名字,叫做 helloworld-streamlit 。
你可以根據(jù)自己的喜好,起名稱。
之后我們就要部署了。
部署的步驟,在上圖中,你可以參考。
注意,上圖中,右上角的 Open App 按鈕,就是你的應(yīng)用鏈接地址,你可以把它記下來(lái)。
首先你需要準(zhǔn)備一些配置文件。
全部的配置文件,我都給你展示在了前文介紹過(guò)的這個(gè) github 項(xiàng)目中,你可以下載回來(lái)復(fù)用。
這里需要說(shuō)明的是,幾個(gè)不同配置文件的用途。
setup.sh 做一些初始設(shè)置,設(shè)定一些參數(shù)。
注意你將來(lái)用的時(shí)候,需要把其中標(biāo)紅的部分,替換成自己注冊(cè) heroku 時(shí)候的郵箱。
requirements.txt 告訴機(jī)器,需要安裝哪些 Python 依賴包。
顯然,教程這里需要的依賴包不多。
Procfile 是遠(yuǎn)端服務(wù)器上, Web 應(yīng)用啟動(dòng)的時(shí)候,需要調(diào)用的腳本。其實(shí)里面只有一行。
請(qǐng)你下載,或者自行編輯上述 3 個(gè)文件后,與你的 Python 文件放在一個(gè)文件夾下面。
之后,請(qǐng)你到這里下載 heroku cli package。
下載后,根據(jù)提示安裝即可。
進(jìn)入終端。用 cd 命令切換到你的工作文件夾,也就是包含了你的 Python 腳本的目錄。
輸入:
heroku?login
因?yàn)槟阋呀?jīng)在 setup.sh 中指定了自己的郵箱,所以這里會(huì)嘗試直接用它來(lái)登錄。
這時(shí)按任意鍵,會(huì)跳出一個(gè)瀏覽器窗口。
在瀏覽器中,點(diǎn)擊確認(rèn)即可登錄。
看到上面的提示,證明登錄成功了。
下面我們來(lái)設(shè)置 git ,這是推送我們文件和更新改動(dòng)的途徑。
在終端下執(zhí)行:
git?init
之后設(shè)置一下與遠(yuǎn)端的 heroku 服務(wù)器的連接:
heroku?git:remote?-a?helloworld-streamlit
若是看到下圖,證明成功了:
然后執(zhí)行:
git?add?.
git?commit?-m?"init"
再執(zhí)行:
git?push?heroku?master
這樣就可以把全部?jī)?nèi)容推送到 heroku 了。
推送的第一步,是上傳文件。
Heroku 發(fā)現(xiàn)咱們推送的是一個(gè) Python App ,所以自動(dòng)執(zhí)行許多安裝設(shè)置工作。
這些安裝和配置做完后,會(huì)出現(xiàn)下面這樣的提示。
到這里,你的 Web 應(yīng)用部署就搞定了。
回到瀏覽器里,用下圖中標(biāo)紅的這個(gè)按鈕開(kāi)啟你自己的應(yīng)用吧。
怎么樣?
很有成就感吧?
思考
嘗試過(guò)之后,你應(yīng)該不難發(fā)現(xiàn),Streamlit 給你帶來(lái)了什么。
如果你學(xué)過(guò) Javascript 和 Flask, Django 等 Web 應(yīng)用開(kāi)發(fā)技術(shù),Streamlit 可以加快你的 Web 應(yīng)用開(kāi)發(fā)與測(cè)試進(jìn)程。
如果你還沒(méi)有學(xué)過(guò)上述技術(shù), Streamlit 就可以給你賦能,讓你一下子有了把數(shù)據(jù)分析結(jié)果變成產(chǎn)品的能力。
給你講點(diǎn)兒更激進(jìn)的。
有人已經(jīng)希望能用它替代掉 Flask 用于產(chǎn)品發(fā)布了。
還有人說(shuō),將來(lái)寫技術(shù)文檔,也應(yīng)該充分使用 Streamlit 。
甚至,還把它比作了數(shù)據(jù)科學(xué)界的 iPhone 。
這里,它是借喻 iPhone 開(kāi)啟智能手機(jī)時(shí)代,說(shuō)明 Streamlit 的劃時(shí)代性。
我不希望你也變得如此激進(jìn)。
因?yàn)檫@里提到的每一種功用,現(xiàn)在還都有非常專業(yè)的工具做的更好,而且新的工具也在不斷涌現(xiàn)。
例如說(shuō),我們?cè)诙鄠€(gè)教程中一直使用 Jupyter Notebook 。
現(xiàn)在憑借 Voila 擴(kuò)展的加持,你也可以很輕松地把 Jupyter Notebook 變成 Web app ,而且可以免費(fèi)運(yùn)行在 mybinder 上面。
但是,你可以看到,一個(gè)新的工具,以一種簡(jiǎn)單,而不是更繁復(fù)的辦法,解決一個(gè)功能痛點(diǎn),是一件多么令人欣喜的事兒。
看了這篇文章,可能會(huì)給你一種誤解,似乎 JavaScript 為代表的前端編程技術(shù),再也不需要學(xué)了。
其實(shí)不是這樣的。
可以想象,開(kāi)發(fā)門檻降低以后,將來(lái)會(huì)有更多的人使用 Python 來(lái)做 Web 應(yīng)用。
用 Streamlit 這樣的方法,他們只是開(kāi)發(fā)出了一個(gè)原型。
要是想打造精品,就必須精細(xì)調(diào)控很多細(xì)節(jié)。
這時(shí)候, Javascript 是繞不過(guò)去的。
如果你精通 Javascript ,那你潛在的合作對(duì)象一下子就多了起來(lái),你掌握的這門技術(shù),也就有了更大的價(jià)值。
還記得嗎?我不止一次給你強(qiáng)調(diào)過(guò),協(xié)作網(wǎng)絡(luò)更重要。忘了的話,記得復(fù)習(xí)《學(xué) Python ,能提升你的競(jìng)爭(zhēng)力嗎?》。
這就好像印刷術(shù)的發(fā)明,不是讓會(huì)寫字這件事兒變得失去價(jià)值,而是全社會(huì)都增大了對(duì)好作品的渴求。深刻的思考,加上有效的文字表達(dá),會(huì)讓你生存得更好。
當(dāng)然,如果你不希望精通寫作技藝,只是想做一個(gè)抄書匠糊口。那么印刷術(shù)就可能會(huì)替代你的工作,結(jié)果就不那么美妙了。
小結(jié)
本文我為你介紹了 Streamlit ,它可以讓你用 Python 腳本編寫簡(jiǎn)潔實(shí)用的交互式 Web 應(yīng)用。
通過(guò)學(xué)習(xí)本文,希望你掌握了以下知識(shí)點(diǎn):
現(xiàn)在你有了一種選擇,僅用純 Python 做一個(gè)完整的交互式數(shù)據(jù)分析產(chǎn)品出來(lái);
如何在讀取數(shù)據(jù)等常用重復(fù)操作中,使用 st.cache 裝飾器提升速度與效率;
如何使用滑動(dòng)條、下拉框等基本組件;
如何在網(wǎng)頁(yè)上輸出文字、表格和圖像;
如何把你本地構(gòu)建和測(cè)試后的 Web 應(yīng)用部署到 Heroku 上,以發(fā)布給你的合作者與客戶。
咱們是以數(shù)據(jù)分析和可視化為例,進(jìn)行了講解。而且為了講解的清晰,我們只介紹了 Streamlit 可實(shí)現(xiàn)功能的一小部分。但請(qǐng)注意,即便是目前, Streamlit 能幫你達(dá)成的目標(biāo),也遠(yuǎn)遠(yuǎn)不止于此。
希望你能夠舉一反三,用 Streamlit 做出令人驚艷的作品。也歡迎你把作品的鏈接在留言區(qū)分享給咱們的同學(xué)。
祝編程愉快!
讀過(guò)本文,如果覺(jué)得有收獲,請(qǐng)點(diǎn)贊。
要讀更多的文章,微信關(guān)注我的公眾號(hào) “玉樹芝蘭”(nkwangshuyi)。別忘了加星標(biāo),以免錯(cuò)過(guò)新推送提示。
如果本文對(duì)你身邊的親友有幫助,也歡迎你把本文通過(guò)微博或朋友圈分享給他們。
延伸閱讀
你可能也會(huì)對(duì)以下話題感興趣。點(diǎn)擊鏈接就可以查看。
題圖:Photo by Luke Chesser on Unsplash
總結(jié)
以上是生活随笔為你收集整理的动态数据交换 python_如何用 Python 和 Streamlit 做交互式数据分析产品?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: python哪个方向简单_现在学Pyth
- 下一篇: python聚类分析成绩反思_机器学习p