'how to create dependent dropdownlist in python and streamlit?

based on the answer of this post i was able to display the dataframe after apply the required filter.

I have a streamlit code that display multiple dropdown lists

  1. first dropdownlist has as option the columns name (its multiselection option)
  2. the other dropdownlists will includes the unique values of the selected columns

enter image description here

what i want is that if the user choose the cat3 and the cat3 does not have a loc2 i want in the third dropdownlist to display just the loc1 and loc3 based on the records of the dataframe.

code:

import numpy as np
import pandas as pd
import streamlit as st 

df =pd.DataFrame({
            "source_number":
             [11199,11328,11287,32345,12342,1232,13456,123244,13456],
             "location":          
             ["loc2","loc1","loc3","loc1","loc2","loc2","loc3","loc2","loc1"],
              "category": 
             ["cat1","cat2","cat1","cat3","cat3","cat3","cat2","cat3","cat2"],
             })  

is_check = st.checkbox("Display Data")
if is_check:
    st.table(df)


columns = st.sidebar.multiselect("Enter the variables", df.columns)

sidebars = {}
for y in columns:
    ucolumns=list(df[y].unique())
    print (ucolumns)

    sidebars[y]=st.sidebar.multiselect('Filter '+y, ucolumns)   

if bool(sidebars):
    L = [df[k].isin(v) if isinstance(v, list) 
         else df[k].eq(v) 
         for k, v in sidebars.items() if k in df.columns]
    
    df1 = df[np.logical_and.reduce(L)]
    st.table(df1)  


Solution 1:[1]

Another workaround could be filtering dataframe before populating each column values and using multiselect's default property in each multiselect instance. Not certain of performance though!

Something like below

with st.sidebar: #1st filter                                     
    FirstFilter = st.mulitiselect(default=df["FirstColumn"].unique())   

df2 = df.query("FirstColumn == @FirstFilter")

with st.sidebar: #2nd filter                                  
    SecondFilter = st.multiselect(deafult=df2["SecondCoulmn"].unique()

df3 = df2.query("SecondColumn == @SecondFilter")

with st.sidebar: #3rd filter*                                       
    ThirdFilter = st.multiselect(default=df3["ThirdColumn"].unique()

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Talha Junaid