iT邦幫忙

2022 iThome 鐵人賽

DAY 9
0
AI & Data

跟著黑蛋用Streamlit速成天文資料分析Web App系列 第 9

[8]:再版系外行星資料表篩選器app,新增資料快取機制

「哎呀!資料表又要重新載入了…」

黑蛋發現目前在系外行星資料表篩選器app中每操作一次篩選,都會再次呼叫get_exoplanet_table_by_astroquery()函式,以致於要再次等待資料表載入。他了解到這是因為Streamlit app是基於一個Python script執行結果所呈現的頁面,每在頁面中做一次操作,會更新Python script中的變數,進而重新執行整個Python script以更新頁面。黑蛋心想,每次都要等待同樣的資料重新載入,這會是一個蠻差的使用者體驗,他得研究看看是否能解決這個問題。

起初,黑蛋找到@st.cache這個decorator可以加在get_exoplanet_table_by_astroquery()函式上方,它會將函式回傳值(value),以及由函式名稱、函式內的程式碼、傳進函式中的參數等資訊所組合成的雜湊值(key),以key-value綁定儲存到快取記憶體中,當函式再次被呼叫時,會先檢查上述資訊的組合是否有變化,若無變化,則略過函式執行步驟,直接從記憶體中取得之前暫存的函式回傳值,以縮減等待時間。

不過,黑蛋進一步發現,Streamlit的開發團隊將會棄用@st.cache,如文件中的說明,因為@st.cache涵蓋不同的使用情境,導致它的程式較為複雜且會拖慢執行速度,所以目前將之拆分成兩個實驗性質的decorator:@st.experimental_memo@st.experimental_singleton,前者用來暫存經由函式計算、下載的資料,後者則是暫存非資料類的物件,例如session、資料庫連線等資訊,未來兩者都會成為正式的功能以取代@st.cache。

黑蛋選擇用@st.experimental_memo來快取get_exoplanet_table_by_astroquery()函式所回傳的資料表,並設定暫存效期為一天。此外,他還用了st.experimental_memo.clear(),讓使用者能為了取得最新的資料表而手動清除快取。如此一來,原本資料表會一直重新載入的問題就解決啦。

# exoplanet_table_filter.py 
import streamlit as st
from astroquery.ipac.nexsci.nasa_exoplanet_archive import NasaExoplanetArchive


@st.experimental_memo(ttl=86400, show_spinner=False)
def get_exoplanet_table_by_astroquery():
    table_name = 'pscomppars'
    columns = 'pl_name,hostname,sy_dist,pl_orbper,pl_bmasse,pl_rade,disc_year,discoverymethod'
    exoplanet_table = NasaExoplanetArchive.query_criteria(
        table=table_name, select=columns
    )
    exoplanet_table = exoplanet_table.to_pandas()
    exoplanet_table = exoplanet_table.rename(
        columns={
            'pl_name': '行星名稱',
            'hostname': '所屬恆星名稱',
            'sy_dist': '與地球的距離(單位:秒差距)',
            'pl_orbper': '行星軌道週期(單位:天)',
            'pl_bmasse': '行星質量(單位:地球質量)',
            'pl_rade': '行星半徑(單位:地球半徑)',
            'disc_year': '發現年份',
            'discoverymethod': '發現方法'
        }
    )
    exoplanet_table.sort_values(
        by='發現年份', ascending=False, inplace=True, ignore_index=True
    )

    return exoplanet_table

# 中略

if st.sidebar.button('清除資料表快取'):
    st.experimental_memo.clear()
    st.balloons()
    st.sidebar.success('已清除快取,請重新載入頁面')

此系列文由蘇羿豪撰寫,以「創用CC 姓名標示 4.0(CC BY 4.0)國際版授權條款」釋出。此系列文也同步在MattersMirror平台連載。


上一篇
[7]:初版一刷系外行星資料表篩選器app
下一篇
[9]:將多個單頁apps整合成一個多頁app
系列文
跟著黑蛋用Streamlit速成天文資料分析Web App30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言