Streamlit筛选需求:未选筛选时显示完整DataFrame
解决Streamlit中筛选条件判断的DataFrame显示问题
问题场景
需要实现Streamlit应用的筛选逻辑:
- 未选择任何筛选条件时,显示完整的DataFrame(
df) - 当选择ID多选框或输入“Preu pagat”数值时,显示筛选后的结果(
dfSelection)
现有基础代码:
import pandas as pd import streamlit as st df = pd.read_csv('classes_particulars.csv') # 筛选组件 idCode = st.sidebar.multiselect( "Selecciona un ID", ('ABSUDUHM', 'DWHWBMMX', 'MIXEECJR', 'NFKQWKOP', 'RQWLPVCJ') ) preuPagat = st.sidebar.number_input( "Preu pagat" ) dfSelection = df.query( "Preu == @preuPagat or ID == @idCode" )
尝试直接用DataFrame做条件判断时触发错误:
if df.query("Preu == @preuPagat or ID == @idCode"): st.table(dfSelection) else: st.table(df)
错误信息:
ValueError: The truth value of a DataFrame is ambiguous. Use a.empty, a.bool(), a.item(), a.any() or a.all().
错误原因
Pandas不允许直接将整个DataFrame作为布尔值用于if判断,因为无法确定是要判断DataFrame是否为空、所有值为真还是任意值为真,因此抛出歧义错误。
正确实现方案
核心思路是判断筛选条件是否被主动触发,而非判断筛选后的DataFrame状态:
- 检查ID多选框是否有选中项(
idCode不为空列表) - 检查“Preu pagat”是否有输入(显式设置默认值,通过对比默认值判断是否修改过输入)
完整修正代码:
import pandas as pd import streamlit as st df = pd.read_csv('classes_particulars.csv') # 筛选组件 idCode = st.sidebar.multiselect( "Selecciona un ID", ('ABSUDUHM', 'DWHWBMMX', 'MIXEECJR', 'NFKQWKOP', 'RQWLPVCJ') ) # 显式设置默认值,避免Preu字段为0时误判筛选状态 preuPagat = st.sidebar.number_input( "Preu pagat", value=0.0 ) # 判断是否有筛选条件被触发 has_filter = bool(idCode) or (preuPagat != 0.0) if has_filter: dfSelection = df.query( "Preu == @preuPagat or ID == @idCode" ) st.table(dfSelection) else: st.table(df)
特殊场景补充
如果业务中Preu字段本身存在0值,可通过session_state跟踪输入框是否被手动修改:
# 初始化状态标记 if 'preu_modified' not in st.session_state: st.session_state['preu_modified'] = False # 输入框绑定修改事件 preuPagat = st.sidebar.number_input( "Preu pagat", value=0.0, on_change=lambda: st.session_state.update({'preu_modified': True}) ) # 更新筛选判断逻辑 has_filter = bool(idCode) or st.session_state['preu_modified']
内容的提问来源于stack exchange,提问作者Adrià Martínez
相关产品推荐
相关产品推荐

