Reputation: 55
I am trying to filter a df based on inputs from the user.. I receive the inputs from 4 drop-down menus as you can see from the picture. Each drop down is the unique()
of a column from the DF however, I added the word "All"
to the top of the list for the drop down menu to disable that specific filter and display the DF without that filter.
def unique(df,col_nme,**kwargs):
lst_nme=df[col_nme].unique()
lst_nme=list(lst_nme)
lst_nme.insert(0,"All")
return lst_nme
and then I set them for display (using streamlit) and construct the filters for pandas
lst_rprt_status = unique(df, "Reporting Status")
rprt_status = st.sidebar.selectbox("Reporting Status", lst_rprt_status)
lst_src = unique(df, "Source")
src = st.sidebar.selectbox("Source", lst_src)
lst_cntrct_type = unique(df, "Contract Type")
cntrct_type = st.sidebar.selectbox("Contract Type", lst_cntrct_type)
lst_country = unique(df, "Country")
country = st.sidebar.selectbox("Country", lst_country)
filt_status = df["Reporting Status"] == rprt_status
filt_src = df["Source"] == src
filt_cntrct_type = df["Contract Type"] == cntrct_type
filt_country = df["Country"] == country
if all the names returns with "All"
, i.e, the user loaded the page, it is quite an easy if statement where i just display the complete DF however, if I start to select values to filter for from the menus while other menus still at "All" or I want to change one to "All"
after it was selected, then I have a problem constructing the combined filter for the DF. I tried reading about df.query but I would run into the same problem.
so basically what I am trying to do here is to have a form of filter like bleow:
df_filtered = df[(df["Reporting Status"] == "Pending") &
(df["Source"] == "All") &
(df["Contract Type"] == "CSA") &
(df["Country"] == "Egypt")]["CPM"]
with the ability to remove a specific line if its associated condition == "All"
, in the above example, would be the df["Source"] == "All"
or add it back when it is not.
I also tried to construct the full sentence with string manipulation but eventually did not work out and I do not want to run an if statements for all the combination that would produce the results unless it is really the only hope
sorry for the long post, but I was trying to be as thorough as possible
Upvotes: 3
Views: 918
Reputation: 920
A standard pattern I use in general is something like
filter = lambda x: choice == 'All' or choice == x
Upvotes: 0
Reputation: 1226
Can you try this? Here i am assuming text All
is reserved for selecting all rows.
What i am doing is first check if the selected input is inside the unique list, if it is not then i select all rows by creating the True
boolean.
msk1 = df["Reporting Status"] == rprt_status if rprt_status in lst_rprt_status else True
msk2 = df["Source"] == src if src in lst_src else True
msk3 = df["Contract Type"] == cntrct_type if cntrct_type in lst_cntrct_type else True
msk4 = df["Country"] == country if country in lst_country else True
df_filtered = (df[msk1 & msk2 & msk3 & msk4])["CPM"]
Upvotes: 1