Updating column value based on data_editor input

Hello

I am very new to Streamlit and I am working with an editable DataFrame within Streamlit using data_editor.

Let’s say I am adding the value 5 to my column ‘A’ through Streamlit and column ‘B’ already contains the value ‘3’.

Initiatiing DataFrame:
df = st.data_editor(df, num_rows='dynamic')

How can I do df['C'] = df['A'] + df['B'] within the app so that column ‘C’ is automatically updated and the value of ‘8’ appears upon entering a value in column ‘A’?

Thanks :slight_smile:

App: locally
Python: 3.10
Streamlit Version: 1.29.0 (via PyPi)

Try this.

from streamlit import session_state as ss, data_editor as de, rerun as rr
import pandas as pd


start_data = {'A': [None, None], 'B': [3, 8], 'C': [None, None]}


if 'start_df' not in ss:
    ss.start_df = pd.DataFrame(start_data)
    ss.start_df['A'] = pd.to_numeric(ss.start_df['A'], errors='coerce').astype('Int64')


def main():
    edited_df = de(ss.start_df, num_rows='dynamic')

    if not ss.start_df.equals(edited_df):
        ss.start_df = edited_df
        ss.start_df.loc[ss.start_df['A'].notna(), 'C'] = ss.start_df['A'] + ss.start_df['B']
        rr()


if __name__ == '__main__':
    main()

I came this while looking for something else. I am trying to do something related to the original question. Instead of summing two columns, I want one column to be dynamically dependent on the value of the widget. Can this be done?

Here is my modifications to your code. But I get the error below.

from streamlit import session_state as ss, data_editor as de, rerun as rr
import pandas as pd
import numpy as np
import streamlit as st

df = pd.DataFrame(
[
{“command”: “text1”, “value”: 1, “is_widget”: True},
{“command”: “text2”, “value”: 0, “is_widget”: False},
{“command”: “text3”, “value”: 1, “is_widget”: True},
]
)

if ‘start_df’ not in ss:
ss.start_df = pd.DataFrame(df)
#ss.start_df[‘value’] = pd.to_numeric(ss.start_df[‘value’], errors=‘coerce’).astype(‘Int64’)

def main():
edited_df = de(ss.start_df)

if not ss.start_df.equals(edited_df):
    ss.start_df = edited_df
    ss.start_df.loc['value'] = np.where(ss.start_df['is_widget'] == True, 1, 0)

    rr()

if name == ‘main’:
main()

Error:
ArrowInvalid: (“Could not convert ‘value’ with type str: tried to convert to int64”, ‘Conversion failed for column None with type object’)

I am a bit mystified as to what I should do. Thanks in advance for any help!

Just use:

ss.start_df = df

@ferdy , i think i could use some help of yours, if you have time.

I have a data_editor with 7 column, which the last one is enabled to user inputs. And then i have a download button to export all the data_editor in xlsx format. But, when i download it, the data from the last column is always empty. I don’t know if i have to use some kind of session_state or not.

PS: there’s a micro download button icon on the top-right of the table, and when i hit it, it downloads a csv with the data from the last column successfully. I wish i had this answer in the forum, but i just can’t find the solution anywhere.

I’m gonna share this snippet. I just have a dataframe (df9) and i create 3 columns (only the last one, called ‘Encomenda (qtd)’, was created to get users input in a data_editor).

Then, i create the data_editor, disabling all columns but ‘Encomenda (qtd)’.
After this, i just have a snippet to create a download button and export all data.

df9['Objetivo de Vendas 2024'] = round(df9['Vendas (qtd) 2023'] * 1.125)
df9['Vendas (qtd) Previstas Mensualizado'] = round(
    df9['Objetivo de Vendas 2024']/12)
df9['Encomenda (qtd)'] = np.nan

st.data_editor(df9,
               column_config={
                   'Encomenda (qtd)': st.column_config.NumberColumn('Encomenda (qtd)'),
                   '': None
               },
               disabled=['CNP', 'SIS', 'Marca/Produto',
                         'Apresentação', 'Vendas (qtd) 2023', 'Objetivo de Vendas 2024', 'Vendas (qtd) Previstas Mensualizado'],
               use_container_width=True,
               hide_index=True)

def convert_df_to_excel(df):
    # Create a BytesIO buffer to save the Excel file
    excel_buffer = io.BytesIO()

    # Use Pandas to write the DataFrame to the buffer as an Excel file
    with pd.ExcelWriter(excel_buffer, engine='xlsxwriter', mode='xlsx') as writer:
        df.to_excel(writer, index=False)

    return excel_buffer


# Applying the function
excel_budget = convert_df_to_excel(df9)

# download button

colunas_1 = st.columns(6)

colunas_1[4].download_button(
    label="Download Budget",
    data=excel_budget,
    file_name='budget.xlsx',
    mime='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
)

Thank you in advance for your patience!!

Define the edited dataframe.

edited_df = st.data_editor(df9, ...)

Convert it.

excel_budget = convert_df_to_excel(edited_df)
1 Like

So simple and just amazing! Thanks a lot, @ferdy , god bless you!

And sorry about my ignorance.