Df does not have .loc in session state

df does not have .loc in the session state

I try to update a df by several multi-select input widget.
The goal is to distribute data over multiple days and create an easy way for a user to move data from one day to another using multi-select. I do this by overwriting the day column in the df for the non-selected category in the df.

This works downstream (using a loop) without problems. However, there might be a situation where someone wants to move data from, f.e. day 4 to day 1, which will not work

I now want to use the session state to change the df upstream, but somehow the .loc function does not work anymore. Am I using the session state wrong?

Code snippet:

'''test'''

import pandas as pd
import streamlit as st

days = 3

input_t = ({
    'cate_name':["A","B","C","D","E","F","G","H","I"],
    'day_df':[1,2,1,2,2,3,1,2,3]
               })
input_df = pd.DataFrame(input_t)

if 'input_df1' not in st.session_state:
    st.session_state['input_df1'] = 0

st.session_state['input_df1'] = input_df

st.write(st.session_state['input_df1'])

cols = st.columns(days)
for j in range(days):
    col = cols[j%5]
    with col:

        blub = st.session_state['input_df1']['cate_name'][st.session_state['input_df1']['day_df']==j+1].tolist()
        bla = st.session_state['input_df1']['cate_name'][st.session_state['input_df1']['day_df']==-1].tolist()
        blub = st.multiselect('Select the participating',
                              blub+bla,
                              blub, key="cat_day" + str(j))
        st.session_state['input_df1'] = st.session_state['input_df1'].loc[(st.session_state['input_df1'].day_df== j+1) & (~st.session_state['input_df1'].cate_name.isin(blub)),'day_df'] = -1
        st.session_state['input_df1'] = st.session_state['input_df1'].loc[(st.session_state['input_df1'].day_df== -1) & (st.session_state['input_df1'].cate_name.isin(blub)),'day_df'] = j+1

missing_cat = st.session_state['input_df1']['cate_name'][st.session_state['input_df1']['day_df']==-1].tolist()
if len(missing_cat) > 0:
    st.warning('The following categories are not scheduled ' + str(missing_cat), icon="āš ļø")

Expected behavior:

I would expect that non-selected data shows at all input widgets as an input option.

Actual behavior:

Error message:

2023-02-06 20:08:38.658 Uncaught app exception
Traceback (most recent call last):
  File "/Library/Frameworks/Python.framework/Versions/3.10/lib/python3.10/site-packages/streamlit/runtime/scriptrunner/script_runner.py", line 562, in _run_script
    exec(code, module.__dict__)
  File "test.py", line 31, in <module>
    st.session_state['input_df1'] = st.session_state['input_df1'].loc[(st.session_state['input_df1'].day_df== j+1) & (~st.session_state['input_df1'].cate_name.isin(blub)),'day_df'] = -1
AttributeError: 'int' object has no attribute 'loc

Debug info

  • Streamlit version: Streamlit, version 1.13.0
  • Python version: python3.10

I somehow think Iā€™m looking with my nose :slight_smile:

First, I would change up the beginning a little:

import pandas as pd
import streamlit as st

days = 3

# Check if you already have a dataframe in session state.
# Initialize it if it isn't there.
if 'input_df1' not in st.session_state:
    input_t = ({
        'cate_name':["A","B","C","D","E","F","G","H","I"],
        'day_df':[1,2,1,2,2,3,1,2,3]
    })
    st.session_state['input_df1'] =  pd.DataFrame(input_t)

st.write(st.session_state['input_df1'])

The problem is here:

The first line kills your stored dataframe, the second line fails because your dataframe is gone. If you are just trying to overwrite some data in your dataframe, get rid of the st.session_state['input_df1'] = at the beginning of these lines.

2 Likes

Hi,
i think the issue is here

 st.session_state['input_df1'] = st.session_state['input_df1'].loc[(st.session_state['input_df1'].day_df== j+1) & (~st.session_state['input_df1'].cate_name.isin(blub)),'day_df'] = -1
 st.session_state['input_df1'] = st.session_state['input_df1'].loc[(st.session_state['input_df1'].day_df== -1) & (st.session_state['input_df1'].cate_name.isin(blub)),'day_df'] = j+1

change this piece to

st.session_state['input_df1'].loc[(st.session_state['input_df1'].day_df== j+1) & (~st.session_state['input_df1'].cate_name.isin(blub)),'day_df'] = -1
st.session_state['input_df1'].loc[(st.session_state['input_df1'].day_df== -1) & (st.session_state['input_df1'].cate_name.isin(blub)),'day_df'] = j+1

should just change the state of the dataframe stored. although i am not sure if it is necessary to store the entire dataframe in session state here.

2 Likes

Hi both,

Indeed the suggestions solved the issue.
I only wanted to change the number in the df, making them available in the selection again!

Thanks a lot for the quick help.

My best,
Claudia