You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Streamlit中如何用单滑块+单按钮更新商品折扣并保留修改?

Streamlit商品折扣更新问题解决方案

问题描述

我正在用Streamlit开发一款应用,输入的DataFrame中包含pant、shirt、jeans等商品的折扣列。需求是让用户灵活更新任意商品的折扣值:

  • 用下拉框选择目标商品
  • 通过滑块调整该商品0-100%的折扣值
  • 点击更新按钮,将调整后的折扣值同步到DataFrame中

但遇到一个问题:当用户更新第二个商品的折扣时,第一个商品的折扣会自动恢复成原始值。

尝试的代码如下:

Key_Input = st.sidebar.selectbox('Select item',df['item'].unique().tolist())
if Key_Input:
    Discount = st.sidebar.slider('Discount', 0.0,1.0, 0.01)
if st.sidebar.button('Update Discount Value'):
    df_new['DISC'] = np.where((df_new['item'] == Key_Input, Discount,df_new['DISC'])
    
st.write(df_new)

问题原因

Streamlit的运行机制是每次用户交互(点击按钮、切换下拉选项),整个脚本会重新执行一遍。你当前的df_new每次都会回到初始状态,之前修改的折扣没有被持久化保存,所以更新第二个商品时,第一个商品的折扣会被重置回原始值。

解决方案

使用Streamlit的st.session_state持久化保存修改后的DataFrame,确保每次交互都基于上一次修改后的状态进行更新。

修正后的代码:

# 初始化会话状态,存入原始DataFrame的副本
if 'updated_df' not in st.session_state:
    st.session_state.updated_df = df.copy()  # df为你的原始DataFrame

# 侧边栏选择商品
Key_Input = st.sidebar.selectbox('Select item', st.session_state.updated_df['item'].unique().tolist())

if Key_Input:
    # 滑块设置折扣值(0-1对应0%-100%)
    Discount = st.sidebar.slider('Discount', 0.0, 1.0, 0.01)

# 更新按钮逻辑
if st.sidebar.button('Update Discount Value'):
    # 精准定位目标商品行,更新折扣列
    st.session_state.updated_df.loc[st.session_state.updated_df['item'] == Key_Input, 'DISC'] = Discount

# 展示更新后的DataFrame
st.write(st.session_state.updated_df)

代码说明

  • st.session_state是Streamlit的会话状态工具,会在用户交互过程中保留数据,不会随脚本重新执行而重置
  • 初始化时存入原始DataFrame的副本,避免直接修改原始数据
  • 用df.loc定位目标商品的行和折扣列,比np.where更直观,更适合DataFrame的行级更新操作

内容的提问来源于stack exchange,提问作者Deepak Goyal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 06:37:15