Streamlit应用用户选择后重复读取DataFrame致卡顿的优化咨询
优化Streamlit大数据表格加载速度方案
核心问题
Streamlit每次用户交互(比如选择下拉框)都会重新执行整个脚本,你的代码每次都重新读取200万行的Excel文件,这是响应慢的根本原因。以下是针对性优化步骤:
1. 用Streamlit缓存缓存数据读取与预处理
使用@st.cache_data装饰器缓存读取和预处理后的DataFrame,确保只有第一次运行时加载数据,后续交互直接复用缓存结果:
import pandas as pd import numpy as np import openpyxl import streamlit as st from streamlit_extras.app_logo import add_logo # page settings st.set_page_config(page_title='FDA-NDC Code Service', layout="wide") st.header('FDA-NDC Code Service') # 用缓存装饰数据读取函数 @st.cache_data def load_and_preprocess_data(): # data reading & pre-processing df = pd.read_excel(io='package.xlsx', engine='openpyxl', sheet_name='package') # 筛选目标列并处理PRODUCTID格式 df = df[["PRODUCTID", "PRODUCTNDC", "NDCPACKAGECODE", "PACKAGEDESCRIPTION", "STARTMARKETINGDATE", "ENDMARKETINGDATE", "NDC_EXCLUDE_FLAG", "SAMPLE_PACKAGE"]] df['PRODUCTID'] = df['PRODUCTID'].str.strip() return df # 加载缓存的数据 df = load_and_preprocess_data() df6 = df.copy() options_pid = df6['PRODUCTID'].unique().tolist() selected_pid = st.sidebar.multiselect('Search product id', options_pid) options_nid = df6['PRODUCTNDC'].unique().tolist() selected_nid = st.sidebar.multiselect('Search product ndc', options_nid) # 修复筛选逻辑:支持同时选择PRODUCTID和PRODUCTNDC if selected_pid and selected_nid: df6 = df6[(df6["PRODUCTID"].isin(selected_pid)) & (df6["PRODUCTNDC"].isin(selected_nid))] elif selected_pid: df6 = df6[df6["PRODUCTID"].isin(selected_pid)] elif selected_nid: df6 = df6[df6["PRODUCTNDC"].isin(selected_nid)] else: st.markdown( f'<p class="header_title"> {str(df6.shape[0])} </p>', unsafe_allow_html=True, ) if selected_pid or selected_nid: st.dataframe(df6.reset_index(drop=True)) else: st.dataframe(df)
2. 替换Excel为更高效的存储格式(强烈推荐)
Excel文件读取速度天生较慢,200万行数据建议先转成Parquet或CSV格式:
- 转Parquet:运行一次
df.to_parquet('package.parquet'),后续读取用pd.read_parquet('package.parquet'),速度比Excel快数倍,还能完整保留数据类型。 - 转CSV:运行一次
df.to_csv('package.csv', index=False),后续读取用pd.read_csv('package.csv'),读取效率也优于Excel。
3. 优化下拉选项渲染(可选)
如果PRODUCTID或PRODUCTNDC的唯一值数量极大,下拉框渲染会变慢,可以:
- 若不需要多选,用
st.selectbox替代multiselect - 对唯一值排序后再生成下拉列表,提升渲染流畅度
内容的提问来源于stack exchange,提问作者rshar
相关产品推荐
相关产品推荐

