如何修复 python 中的错误 "DataFrame object is not callable" 和 streamlit

how to fix error "DataFrame object is not callable" in python and streamlit

我有一个 python 代码显示 dataframe 并允许用户通过创建 new dataframe 来过滤数据帧并允许他使用 selectedbox 中的索引号更新请求的记录。

出于这个原因,我正在使用 streamlit 会话状态 的新功能,我希望系统在 用户更改值后保留过滤后的数据帧selectbox 通过使用 回调功能

问题是,一旦用户 select 来自 select 框的值,系统崩溃并显示以下错误:

TypeError: 'DataFrame' object is not callable
Traceback:
File "F:\AIenv\lib\site-packages\streamlit\script_runner.py", line 347, in _run_script
    self._session_state.call_callbacks()
File "F:\AIenv\lib\site-packages\streamlit\state\session_state.py", line 379, in call_callbacks
    self._new_widget_state.call_callback(wid)
File "F:\AIenv\lib\site-packages\streamlit\state\session_state.py", line 203, in call_callback
    callback(*args, **kwargs)

代码:

import pandas as pd
import streamlit as st
        
def update_df(new_df):
    return pd.DataFrame(new_df)
        
def main():
    df=pd.read_csv(data)
    df_result_search = pd.DataFrame.from_records(df, columns = [column[0] for column in cursor.description])
    df_len = range(len(df_result_search.index))
    s = st.selectbox('Select index',key="select_box",options=df_len,on_change=update_df(df_result_search))
    expander_updates_fields = st.beta_expander('Update Records')
    with expander_updates_fields:
            for i, col in enumerate(df.columns):
                  if not s == 0:
                     val_update = st_input_update('Update {} from {} to:'.format(col, df[col].values[s]))
                     expander_updates_fields.markdown(val_update, unsafe_allow_html=True)
                  else:
                      st.write("DataFrame is empty")
    
    
if __name__=='__main__':
    main()
            

基于 Joran Beasley

的回答

系统 return selected 值但未显示数据帧

在用户 select 值页面刷新后发生了什么:

  1. 数据框消失
  2. select框保存了 selected 值
  3. 更新扩展器return每个中所有记录的所有值 列。

因此,出于这个原因,我使用了 callback()

我想要的是:

  1. 数据帧仍然出现。
  2. select框保存了 selected 值
  3. selected 索引号的更新扩展器 return 值 每个 列。

我怎样才能完成这3个任务???

尝试做

on_change=lambda: update_df(df_result_search)

在你基本上拥有

之前
a_df = update_df(df_result_search)
... on_change=a_df

on_change 需要一个可以调用的函数……它不能调用返回的数据帧……在建议的解决方案中,我们只需将其转换为一个 lambda,当 select 选择已更改。

(粗略地说,它可能会传递某种“change_event”,您可能应该将其用于 select 列或其他内容)

...on_change= lambda evt:do_something_with_event(evt)

进一步检查,我认为您不太了解 streamlit 的工作原理

此示例应该可以帮助您理解为什么仍然存在一些问题

import streamlit as st


def main():
    s = st.selectbox('Select index',key="select_box",options=['a','b','c'],on_change=lambda *a:print("Old selection:",s))
    print("Current selection:",s) # now do something with it

if __name__=='__main__':
    main()