day23-Excel智能体项目

pandas操作代码.ipynb

数据分析处理平台

pip install openpyxl

基于streamlit结合openai agent sdk实现。

import streamlit as st
import pandas as pd
import asyncio
from openai import AsyncOpenAI
from agents import OpenAIChatCompletionsModel, Agent, Runner, set_default_openai_client
from io import BytesIO
from agents import function_tool
import textwrap

@function_tool
def null_col_remove():
    '''
    该函数的作用是用来将用户上传的文件数据中空值所在的行全部进行删除。
    :return:返回删除后的状态信息
    '''
    print("正在调用删除空值所在行的外部函数。")
    code = '''
    drop_df = df.dropna()
    drop_df.to_excel("updateFile.xlsx")
    '''
    #dedent用来剔除无效缩进
    code = textwrap.dedent(code)
    try:
        exec(code)
    except Exception as e:
        print(e)
    return '已成功将空值所在的行全部进行删除!'

@function_tool
def repeat_index_remove():
    '''
    该函数的作用是用来将用户上传的文件数据中重复的行数据进行删除。
    :return:返回删除后的状态信息
    '''
    print("正在调用删除重复行数据的外部函数。")
    code = '''
    dup_df = df.drop_duplicates()
    dup_df.to_excel("updateFile.xlsx")
    '''
    #dedent用来剔除无效缩进
    code = textwrap.dedent(code)
    try:
        exec(code)
    except Exception as e:
        print(e)
    return '已成功将空值所在的行全部进行删除!'
# 页面配置
st.set_page_config(
    page_title="DeepSeek Excel智能助手",
    page_icon="🤖",
    layout="wide"
)

# 初始化session state
if "chat_history" not in st.session_state:
    st.session_state.chat_history = []
if "excel_data" not in st.session_state:
    st.session_state.excel_data = None
if "processed_data" not in st.session_state:
    st.session_state.processed_data = None
if "agent" not in st.session_state:
    st.session_state.agent = None

# 标题
st.title("🤖 DeepSeek Excel智能助手")
st.markdown("---")

# 侧边栏 - 配置区域
with st.sidebar:
    st.header("⚙️ 配置设置")
    
    # API Key输入
    api_key = st.text_input(
        "🔑 输入DeepSeek API Key",
        type="password",
        placeholder="sk-xxxxxxxxxxxxxxxx",
        help="请从DeepSeek平台获取您的API Key"
    )
    
    # 文件上传
    uploaded_file = st.file_uploader(
        "📊 上传Excel文件",
        type=["xlsx", "xls", "csv"],
        help="支持Excel和CSV格式的文件"
    )
    
    # 处理上传的文件
    if uploaded_file is not None:
        try:
            if uploaded_file.name.endswith('.csv'):
                df = pd.read_csv(uploaded_file)
            else:
                df = pd.read_excel(uploaded_file)
            
            st.session_state.excel_data = df
            st.session_state.processed_data = df.copy()  # 初始化处理后的数据
            st.success(f"✅ 文件上传成功!数据维度: {df.shape[0]}行 × {df.shape[1]}列")
            
        except Exception as e:
            st.error(f"❌ 文件读取失败: {str(e)}")
    
    # 初始化Agent按钮
    if st.button("🚀 初始化AI助手", type="primary"):
        if not api_key:
            st.error("❌ 请输入API Key")
        else:
            try:
                # 创建客户端
                external_client = AsyncOpenAI(
                    base_url="https://api.deepseek.com",
                    api_key=api_key,
                )
                
                # 设置默认客户端
                set_default_openai_client(external_client)
                
                # 创建模型
                deepseek_model = OpenAIChatCompletionsModel(
                    model="deepseek-chat",
                    openai_client=external_client
                )
                
                # 创建智能Agent
                agent = Agent(
                    name="Excel数据分析助手",
                    instructions="""你是一名专业的数据分析师和智能助手。根据用户需求,你可以:

1. **普通对话**:回答各种问题,提供帮助和建议
2. **Excel数据分析**:当用户上传Excel文件后,你可以:
   - 深度理解数据结构和业务含义
   - 进行空值检测和分析
   - 提供数据质量评估
   - 给出数据洞察和建议
   - 回答关于数据的各种问题
   - 执行数据处理操作(如删除空行、数据清洗等)

请根据用户意图自动识别需要执行的功能,用专业但易懂的语言回答问题。""",
                    model=deepseek_model,
                    tools=[null_col_remove,repeat_index_remove]
                )
                
                st.session_state.agent = agent
                st.success("✅ AI助手初始化成功!")
                
            except Exception as e:
                st.error(f"❌ 初始化失败: {str(e)}")
    
   

# 数据显示区域
if st.session_state.excel_data is not None:
    df = st.session_state.excel_data
    
    with st.expander("📊 当前数据概览", expanded=False):
        col1, col2, col3, col4 = st.columns(4)
        with col1:
            st.metric("总行数", df.shape[0])
        with col2:
            st.metric("总列数", df.shape[1])
        with col3:
            st.metric("空值数量", df.isnull().sum().sum())
        with col4:
            st.metric("数据大小", f"{df.memory_usage(deep=True).sum() / 1024**2:.2f} MB")
        
        # 显示列信息
        st.subheader("📋 数据列信息")
        col_info = pd.DataFrame({
            '列名': df.columns,
            '数据类型': df.dtypes.values,
            '非空值数量': df.count().values,
            '空值数量': df.isnull().sum().values
        })
        st.dataframe(col_info)

# 聊天区域
st.header("💬 智能对话")

# 显示聊天历史
for message in st.session_state.chat_history:
    with st.chat_message(message["role"]):
        st.markdown(message["content"])

# 聊天输入
if prompt := st.chat_input("请输入您的问题或数据分析需求..."):
    # 添加用户消息到历史
    st.session_state.chat_history.append({"role": "user", "content": prompt})
    
    # 显示用户消息
    with st.chat_message("user"):
        st.markdown(prompt)
    
    # 显示AI回复
    with st.chat_message("assistant"):
        if st.session_state.agent is None:
            st.warning("⚠️ 请先在侧边栏初始化AI助手")
        else:
            try:
                # 准备上下文信息
                context = ""
                if st.session_state.excel_data is not None:
                    df = st.session_state.excel_data
                    data_info = f"""
                    当前Excel数据信息:
                    - 数据形状: {df.shape[0]}行, {df.shape[1]}列
                    - 列名: {list(df.columns)}
                    - 数据类型: {dict(df.dtypes)}
                    - 空值统计: {df.isnull().sum().to_dict()}
                    - 数据预览 (前3行):
                    {df.head(3).to_string()}
                    """
                    context = f"\n\n{data_info}\n\n请基于以上数据信息回答用户的问题。"
                
                # 运行Agent
                with st.spinner("🤔 思考中..."):
                    result = asyncio.run(Runner.run(
                        st.session_state.agent, 
                        [{"role": "user", "content": prompt + context}]
                    ))
                
                response = result.final_output
                st.markdown(response)
                
                # 添加AI回复到历史
                st.session_state.chat_history.append({"role": "assistant", "content": response})
                
                
            except Exception as e:
                error_msg = f"❌ 处理请求时出错: {str(e)}"
                st.error(error_msg)

# 清空聊天历史按钮
if st.session_state.chat_history:
    if st.button("🗑️ 清空聊天历史"):
        st.session_state.chat_history = []
        st.rerun()

# 使用提示
with st.expander("💡 使用提示", expanded=False):
    st.markdown("""
    **您可以这样提问:**
    
    📊 **数据分析类:**
    - "分析一下这个数据集的整体情况"
    - "这个数据集有什么问题需要注意?"
    - "帮我理解每列数据的含义"
    
    🔧 **数据处理类:**
    - "删除所有空行"
    - "清除重复数据"
    
    🔍 **数据查询类:**
    - "显示前10行数据"
    - "有哪些数值类型的列?"
    
    💬 **普通对话类:**
    - "你好,请介绍一下你自己"
    - "数据分析的最佳实践是什么?"
    """)

# 页脚
st.markdown("---")
st.markdown(
    "<div style='text-align: center; color: gray;'>"
    "Powered by DeepSeek API & OpenAI Agents SDK"
    "</div>",
    unsafe_allow_html=True
)
posted @ 2025-11-07 11:20  凫弥  阅读(5)  评论(0)    收藏  举报