黑蛋收到一則從Asana專案管理軟體傳來的任務通知,標題為:「研究能快速篩選系外行星資料表的方法」,PM貳婰舞在任務描述區塊中貼了一個錄影連結,他在影片中說明:「雖然我們現在能藉由程式取得並匯出系外行星資料表,但客戶時常會有資料篩選的需求,例如,他有時只要某年份區間內被發現的行星,或是只要被某個方法發現的行星,或是要去除某幾個欄位值為空值的行星,所以需要請你研究能快速篩選系外行星資料表的方法。」
黑蛋心想,雖然能用Google Sheets等工具過濾由程式產生的系外行星資料表,但若能將資料取得、篩選、匯出等功能都集中在同一地方或許比較方便,所以,他想試試Streamlit能否做到。
首先,他開啟一個命名為exoplanet_table_filter.py的Python script,將前幾天研究Astroquery套件時寫好的函式get_exoplanet_table_by_astroquery()擺了進去,加上頁面標題及app簡介後,呼叫該函式並呈現系外行星資料表。不過,他發現在資料表載入時會等待一段時間,為了讓使用者體驗好一些,他使用st.spinner元件來呈現「正在載入系外行星資料表,請稍候...」的訊息。
# exoplanet_table_filter.py
import streamlit as st
from astroquery.ipac.nexsci.nasa_exoplanet_archive import NasaExoplanetArchive
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
page_title = '系外行星資料表篩選器'
st.set_page_config(page_title=page_title, page_icon=':star', layout='wide')
st.title(page_title)
st.info('藉由[Astroquery](https://astroquery.readthedocs.io/en/latest/ipac/nexsci/nasa_exoplanet_archive.html)套件取得[NASA系外行星資料庫](https://exoplanetarchive.ipac.caltech.edu/)提供的資料表,篩選出所需資料後匯出CSV檔。')
with st.spinner('正在載入系外行星資料表,請稍候...'):
exoplanet_table = get_exoplanet_table_by_astroquery()
st.dataframe(exoplanet_table)
接著,黑蛋找齊用來組裝篩選功能的元件:以st.select_slider篩選年份範圍、用st.selectbox篩選發現方法、用st.multiselect多選要去除空值的欄位,另外,他還用了st.sidebar以便將這些元件集中放在側邊欄。最後,他安置了st.download_button,讓使用者可以將篩選後的資料表匯出成CSV檔,這樣系外行星資料表篩選器app就完成啦!完整的程式碼如下:
# exoplanet_table_filter.py
import streamlit as st
from astroquery.ipac.nexsci.nasa_exoplanet_archive import NasaExoplanetArchive
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
page_title = '系外行星資料表篩選器'
st.set_page_config(page_title=page_title, page_icon=':star', layout='wide')
st.title(page_title)
st.info('藉由[Astroquery](https://astroquery.readthedocs.io/en/latest/ipac/nexsci/nasa_exoplanet_archive.html)套件取得[NASA系外行星資料庫](https://exoplanetarchive.ipac.caltech.edu/)提供的資料表,篩選出所需資料後匯出CSV檔。')
with st.spinner('正在載入系外行星資料表,請稍候...'):
exoplanet_table = get_exoplanet_table_by_astroquery()
year_min = int(exoplanet_table['發現年份'].min())
year_max = int(exoplanet_table['發現年份'].max())
year_lst = list(range(year_min, year_max + 1))
year_range = st.sidebar.select_slider(
'篩選某年份區間內被發現的行星',
options=year_lst,
value=(year_min, year_max),
)
exoplanet_table = exoplanet_table[
(exoplanet_table['發現年份'] >= year_range[0]) &
(exoplanet_table['發現年份'] <= year_range[1])
]
method_lst = sorted(list(exoplanet_table['發現方法'].unique()))
selected_method = st.sidebar.selectbox(
'篩選被某個方法發現的行星', ['不限'] + method_lst
)
if selected_method != '不限':
exoplanet_table = exoplanet_table[exoplanet_table['發現方法'] == selected_method]
column_name_lst = list(exoplanet_table.columns)
selected_columns = st.sidebar.multiselect(
'去除某幾個欄位值為空值的行星', column_name_lst
)
exoplanet_table = exoplanet_table.dropna(subset=selected_columns)
exoplanet_table = exoplanet_table.reset_index(drop=True)
st.dataframe(exoplanet_table)
st.sidebar.download_button(
label='將篩選資料表匯出成CSV檔',
data=exoplanet_table.to_csv(index=False),
file_name='exoplanet_table.csv',
mime='text/csv'
)
此系列文由蘇羿豪撰寫,以「創用CC 姓名標示 4.0(CC BY 4.0)國際版授權條款」釋出。此系列文也同步在Matters及Mirror平台連載。