Maintaining DataFrame After Filtering

I am using the amazing DataFrame filter, and I’m having a hard time keeping the DataFrame after I click on the filter.

The problem is that I get this DataFrame from an API response, which comes from a lot of filters that the user makes.

If I use the following: st.session_state.clicked, everything works well. However, there is a problem if the user changes the date or the domain in the filter, for example. The app sends another request to the API, and sometimes the user hasn’t even finished typing, leading to an error.

So I thought of maybe just using an ‘if button’. With that, I would be sure that the user clicked the button to send another API request. However, using this approach, I can’t have the filter in the DataFrame.

I have already tried caching the DataFrame and using session states, but I haven’t achieved any results so far. I think I might be doing something very wrong.

Here is my code:

with c2:
    tab1, tab2 = st.tabs(["📅 Date", "📃 Table"])
    with tab1:
        if button:
            # Get data for the "Date" tab
            df_date = get_data_date(property_url, day[0].strftime("%Y-%m-%d"), day[1].strftime("%Y-%m-%d"),
                    url_filter=url_filter, url_operator=url_operator,
                    word_filter=word_filter, word_operator=word_operator)
                           
            # Group data by date and calculate some metrics
            df_grouped = df_date.groupby('Date').agg({
                'Clicks': 'sum',
                'Impressions': 'sum',
                'CTR': 'mean',
                'Position': 'mean'
            }).reset_index()

            # Plot the chart with metrics grouped by date
            fig = plot_chart(df_grouped)
            
            # Calculate some general metrics
            Clicks = df_date['Clicks'].sum()
            Impressions = df_date['Impressions'].sum()
            ctr_mean = df_date['CTR'].mean()
            pos_mean = df_date['Position'].mean()
            df_date['CTR'] = df_date['CTR'].apply(lambda ctr: f"{ctr * 100:.2f}%")
            
            # Display metrics in card format
            met1, met2, met3, met4 = st.columns(4)
                
            with met1:
                st.metric('Clicks:', f'{Clicks:,}'.replace(',', '.'))
            with met2:
                st.metric('Impressions:', f'{Impressions:,}'.replace(',', '.'))
            with met3:
                st.metric('CTR:', f'{ctr_mean * 100:.2f}%')
            with met4:
                st.metric('Avg. Position:', f'{pos_mean:.1f}')
                
            # Plot the chart with metrics grouped by date
            st.plotly_chart(fig, config={'displayModeBar': False}, theme="streamlit", use_container_width=True)
            
            # Button to download data in Excel format
            df_xlsx = to_excel(df_date)
            st.download_button(label='📥 Download Excel',
                            data=df_xlsx,
                            file_name='GSC-API-Data.xlsx')

Hey, I think I’ve managed to make it work.

I changed the functionality to make the button store a dataframe in a session state. Then I check if there is a dataframe in the session state and create my filter using this new dataframe.

What was:

    with tab1:
        if button:
            # Get data for the "Date" tab
            df_date = get_data_date()
                           
            # Group data by date and calculate some metrics
            df_grouped = df_date.groupby('Date').agg({
                'Clicks': 'sum',
                'Impressions': 'sum',
                'CTR': 'mean',
                'Position': 'mean'
            }).reset_index()

Now is:

        with tab1:
            if button:
                # Obtém os dados para a aba "Data"
                df_date = get_data_date()
                
                st.session_state.dataframeData = df_date
            if hasattr(st.session_state, 'dataframeData'):
                try:
                    novo_df = st.session_state.dataframeData                   
                    # Agrupa os dados por data e calcula algumas métricas
                    df_grouped = novo_df.groupby('Data').agg({
                        'Cliques': 'sum',
                        'Impressões': 'sum',
                        'CTR': 'mean',
                        'Posição': 'mean'
                    }).reset_index()

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.