Фильтрация pandas на основе различных условий, поскольку входные данные от пользователя - PullRequest
2 голосов
/ 19 июня 2020

Я пытаюсь отфильтровать df на основе входных данных пользователя. Я получаю входные данные из 4 раскрывающихся меню, как вы можете видеть на картинке. Каждое раскрывающееся меню - это unique() столбца из DF, однако я добавил слово "All" в верхнюю часть списка для раскрывающегося меню, чтобы отключить этот фильтр c и отобразить DF без этого фильтра. Выпадающие меню

вот как составляется список каждого меню

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

, а затем я устанавливаю их для отображения (используя streamlit) и создаю фильтры для 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

если все имена возвращаются с "All", т. Е. Пользователь загрузил страницу, это довольно простой оператор if, в котором я просто отображаю полный DF, однако, если я начну выбирать значения для фильтрации из меню, в то время как другие меню все еще находятся в состоянии «Все», или я хочу изменить одно на "All" после его выбора, тогда у меня возникнет проблема с построением комбинированного фильтра для DF. Я пробовал читать о df.query, но столкнулся с той же проблемой.

поэтому в основном то, что я пытаюсь сделать здесь, - это иметь такой фильтр, как bleow:

        df_filtered = df[(df["Reporting Status"] == "Pending") &
                     (df["Source"] == "All") &
                     (df["Contract Type"] == "CSA") &
                     (df["Country"] == "Egypt")]["CPM"]

с возможностью удаления определенной строки c, если связанное с ней условие == "All" в приведенном выше примере будет df["Source"] == "All", или добавить его обратно, если это не так. Я также попытался построить полное предложение с помощью строковых манипуляций, но в итоге у меня ничего не вышло, и я не хочу запускать операторы if для всей комбинации, которая дала бы результат, если только это не единственная надежда

извините для длинного поста, но я старался быть максимально подробным

Ответы [ 2 ]

1 голос
/ 21 июня 2020

Можешь попробовать это? Здесь я предполагаю, что текст All зарезервирован для выбора всех строк.

Я сначала проверяю, находится ли выбранный ввод внутри уникального списка, если это не так, я выбираю все строки, создавая True логическое.

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"]

0 голосов
/ 21 июня 2020

Стандартный шаблон, который я обычно использую, выглядит примерно так:

filter = lambda x: choice == 'All' или choice == x

...