Julie-Anne
Julie-Anne

Reputation: 23

Streamlit save user data and update CSV

I have a streamlit app which calculates outputs based on inputs added by users.

My users would like to keep track / log their outputs in a table or dataframe.

Here is my current code:

d = {'time' : timestamp,
    'Primary Air Flow Rate': qavalue, 
 'Primary Air Temperature': travalue,
 'Reference Air Remperature': trvalue,
 }

d = pd.DataFrame(data=d,index=[0])
results_option1 = pd.read_csv('results_option1.csv')

clickSubmit = st.button('Save values')

if clickSubmit == True: 
    
    results_option1 = results_option1.append(d,ignore_index=True)
    open('results_option1.csv','a').write(results_option1.to_csv())
else :
    st.markdown("Please submit to save")

st.write(results_option1)

While this 'works' everytime a user adds new data, it creates a new column called "Unnamed : 0.n". There are as many extra columns as there are entries. I believe it's because it can't find my index but I'm not sure.

streamlit table

Also when I open the csv file, the first cell in my file begins with a comma and not the name of the first column so I don't know why it adds a comma at the very beginning with each new entry.

Any idea on how to fix? Many thanks

Upvotes: 0

Views: 1325

Answers (2)

HHest
HHest

Reputation: 821

This is an issue with how you're using to_csv and read_csv, and pandas in general, not a streamlit issue.

Since the index isn't relevant to you, you should use to_csv(..., index=False), and when you read the file, you should use read_csv(..., index_col=False)

Reference:

https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.DataFrame.to_csv.html https://pandas.pydata.org/pandas-docs/stable/reference/api/pandas.read_csv.html

Here's the full code, with some reorg/modifications:

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


csv_file = 'results_option1.csv'
if os.path.exists(csv_file):
    # read from file
    results_option1 = pd.read_csv(csv_file, index_col=False)
else:
    # create empty dataframe with the right columns & dtypes
    results_option1 = pd.DataFrame(
        {'time': np.array([]).astype('datetime64[ns]'),
         'Primary Air Flow Rate': np.array([], dtype=np.float64),
         'Primary Air Temperature': np.array([], dtype=np.float64),
         'Reference Air Temperature': np.array([], dtype=np.float64),
         }
    )

st.write('before')
st.dataframe(results_option1)

with st.form('input_form'):
    qavalue = st.number_input('Primary Air Flow Rate')
    travalue = st.number_input('Primary Air Temperature')
    trvalue = st.number_input('Reference Air Temperature')
    clickSubmit = st.form_submit_button('Submit')

if clickSubmit:
    timestamp = datetime.datetime.now()
    results_option1.loc[len(results_option1)] = [timestamp, qavalue, travalue, trvalue]
    results_option1.to_csv(csv_file, index=False)
    st.write('after')
    st.dataframe(results_option1)
else:
    st.markdown("Please submit to save")

Upvotes: 0

rafidini
rafidini

Reputation: 216

  1. You could use the pd.DataFrame.from_dict(d) to make it easier for you to ensure the columns when reading the dictionary
  2. As for the append, try out pd.concat([d1, d2]) as pd.append is Deprecated since version 1.4.0

References

But make sure of the package version to apply these modifications of course.

Hope it helps!

Upvotes: 1

Related Questions