CSV数据分析智能工具(基于OpenAI API和streamlit)

utils.py:

from langchain_openai import ChatOpenAI
from langchain_experimental.agents.agent_toolkits import create_csv_agent
import json

PROMPT_TEMPLATE = """
    你是一位数据分析助手,你的回应内容取决于用户的请求内容。

    1. 对于文字回答的问题,按照这样的格式回答:
        {"answer": "<你的答案写在这里>"}
    例如:
        {"answer": "订单量最高的产品ID是!MNWC3-067"}

    2. 如果用户需要一个表格,按照这样的格式回答:
        {"table": {"columns": ["column1", "column2", ...], "data": [[value1, value2, ...],[value1, value2, ...],...]}}

    3. 如果用户的请求适合返回条形图,按照这样的格式回答:
        {"bar": {"columns": ["A", "B", "C", ...], "data": [34, 21, 91, ...]}}

    4. 如果用户的请求适合返回折线图,按照这样的格式回答:
        {"line": {"columns": ["A", "B", "C", ...], "data": [34, 21, 91, ...]}}

    5. 如果用户的请求适合返回散点图,按照这样的格式回答:
         {"scatter": {"columns": ["A", "B", "C", ...], "data": [34, 21, 91, ...]}}
    注意:我们只支持三种类型的图表:"bar", "line" 和 "scatter"。

    请将所有输出作为JSON字符串返回。请注意要将"columns"列表和数据列表中的所有字符串都用双引号包围。
    例如:{"columns": ["Products", "Orders"], "data": [["32085Lip", 245], ["76439Eye", 178]]}

    你要处理的用户请求如下:
    """

def dataframe_agent(api_key, uploaded_file, query):
    model = ChatOpenAI(model="gpt-4",
                       api_key=api_key,
                       base_url="https://api.gptsapi.net/v1",
                       temperature=0)
    
    # path 复制文件到本地,得到路径
    file_content = uploaded_file.getvalue() #.read()改成.getvalue(),就能读了
    print(file_content)
    print(type(file_content))
    print(type(file_content))
    file_path = "temp.csv"
    with open(file_path,"wb") as fwb:
        fwb.write(file_content)
 
    
    # agent执行器
    agent_executor = create_csv_agent(
        llm=model,
        path=file_path,
        allow_dangerous_code=True,
        agent_executor_kwargs={
            "handle_parsing_errors": True
        },
        verbose=True
    )

    # 输入 = 我们补充的提示 + 用户输入
    prompt = PROMPT_TEMPLATE + query
    result = agent_executor.invoke({
        "input": prompt
    })

    # result_dict = json.loads(result["output"]) #实际输出的内容是output键对应的值,然后把它解析成字典,方便前端使用
    # return result_dict
    try : result_dict = json.loads(result["output"]) #实际输出的内容是output键对应的值,然后把它解析成字典,方便前端使用
    finally : print(result["output"])
    return result_dict

# # 自定义一个类来模拟 UploadedFile 对象
# class CustomUploadedFile:
#     def __init__(self, name, type, data):
#         self.name = name
#         self.type = type
#         self.data = data
#         self.size = len(data)

#     def read(self):
#         return self.data

# # 自定义一个函数将文件路径转换为类似 UploadedFile 的对象
# def file_path_to_uploaded_file(file_path):
#     with open(file_path, 'rb') as f:
#         file_content = f.read()
#     file_name = file_path.split("/")[-1]  # 获取文件名
#     file_type = "text/csv"  # 假设是 CSV 文件,可根据实际情况修改
#     return CustomUploadedFile(file_name, file_type, file_content)

# # 示例文件路径
# file_path = "test_data.csv"

# # 转换为 UploadedFile 对象
# uploaded_file = file_path_to_uploaded_file(file_path)

# import os 
# import pandas as pd

# print(dataframe_agent(os.getenv("OPENAI_API_KEY"),uploaded_file,"数据里score的范围是什么"))

 main.py:

import streamlit as st
from utils import dataframe_agent
import pandas as pd
import os

def create_chart(input_data, chart_type):
    # 检查"data"字段是否存在且非空
    if "data" not in input_data or not input_data["data"]:
        st.error("没有提供有效的数据来创建图表")
        return
    
    data = input_data["data"]
    
    # 如果数据看起来像是一维的(即单列数据)
    if all(isinstance(i, (int, float)) for i in data):
        df = pd.DataFrame(data, columns=input_data["columns"])
    else:
        # 假设数据是二维的(多列数据)
        df = pd.DataFrame(data, columns=input_data["columns"])
    
    if chart_type == "line":
        st.line_chart(df)
    elif chart_type == "bar":
        st.bar_chart(df)
    # 可以添加更多图表类型的支持
    else:
        st.error(f"不支持的图表类型: {chart_type}")


st.title("CSV数据分析智能工具")

with st.sidebar:
    api_key = st.text_input("请输入你的OpenAI API密钥", type="password") 
    st.markdown("[获取OpenAI API密钥](https://2233.ai/api)")

    # 上传文件
    csv_file = st.file_uploader("请上传你的csv格式数据文件:", type="csv")

# 展示部分文件数据
if csv_file:
    df = pd.read_csv(csv_file)
    with st.expander("原始数据"):
        st.dataframe(df)

query = st.text_area("请输入你关于以上表格的问题,或数据提取请求,或可视化请求(支持散点图、折线图、条形图):", disabled=not csv_file)

button = st.button("生成回答")

if button:
    if not api_key:
        st.info("请先输入OpenAI API密钥")
        st.stop()
    if not query:
        st.info("请输入您的问题")
        st.stop()
    
    with st.spinner("AI正在思考中,请稍等···"):
        result_dict = dataframe_agent(api_key=api_key, uploaded_file=csv_file, query=query)
        
        if "answer" in result_dict:
            st.write(result_dict["answer"])
        if "table" in result_dict:
            columns = result_dict["table"]["columns"]
            data = result_dict["table"]["data"]
            df_result = pd.DataFrame(data, columns=columns)
            st.table(df_result)
        if "bar" in result_dict:
            create_chart(result_dict["bar"], "bar")
        if "line" in result_dict:
            create_chart(result_dict["line"], "line")
        if "scatter" in result_dict:
            create_chart(result_dict["scatter"], "scatter")

1、由于对于不同的响应内容,前端展示不同

比如:直接输出字符串答案,或者绘制表格、条形图、散点图、折线图等。

 

所以要设计提示词,引导ai对不同内容进行区分。

一个办法是,规定响应的答案格式是字典,里面的键值表示了是什么样的内容(比如answer对应字符串内容,table表示表格,bar条形图,line折线图,scatter散点图),

易于后续分类讨论解析。 

 

注意:仔细检查prompt有没有格式错误,或者中英文标点符号错误

2、json.loads 是 Python 标准库 json 模块中的一个重要函数,主要用于将 JSON 格式的字符串解析为 Python 对象。

 

3、

从你给出的错误信息可知,在调用 create_csv_agent 或者 create_pandas_dataframe_agent 时,程序抛出了 ValueError 异常。

错误原因:

create_pandas_dataframe_agent 这类代理会依赖 Python REPL(交互式解释器)工具来执行任意代码,这存在安全风险。为了防止潜在的安全问题,在使用此功能前,你必须明确表示同意使用,也就是要把 allow_dangerous_code 参数设置为 True。 

 

4、把file_content = uploaded_file.read()改成file_content = uploaded_file.getvalue() 

因为前端里有一句df=pd.read_csv(csv_file),会让读指针移到文件末尾,所以再用read读就是空。

补充:

关闭文件后,文件指针并不会回到最开始的位置,文件对象也不再处于可用状态,无法直接获取其指针位置信息。

 

当你调用文件对象的close()方法关闭文件时,系统会释放与该文件相关的资源,包括文件描述符等。此时,文件对象在内存中的状态被改变,不再维护之前的文件指针位置。如果后续你想要再次读取文件内容,需要重新打开文件,而重新打开文件时,文件指针默认会位于文件开头(除非你使用特定的模式打开文件,例如以追加模式'a''a+'打开文件,文件指针会位于文件末尾 )。

 

5、

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/964849.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2025.2.5

Web [SWPUCTF 2021 新生赛]ez_unserialize: 这个题先了解一下反序列化&#xff1a;反序列化是序列化的逆过程。序列化是将对象或数据结构转换为可以存储或传输的格式&#xff08;如JSON、XML或二进制格式&#xff09;的过程。反序列化则是将这个格式的数据转换回原始的对象或…

新版AndroidStudio 修改 jdk版本

一、问题 之前&#xff0c;在安卓项目中配置JDK和Gradle的过程非常直观&#xff0c;只需要进入Android Studio的File菜单中的Project Structure即可进行设置&#xff0c;十分方便。 如下图可以在这修改JDK: 但是升级AndroidStudio之后&#xff0c;比如我升级到了Android Stu…

Web3技术详解

Web3技术代表着互联网技术的最新进展&#xff0c;它致力于打造一个去中心化的互联网生态系统。以下是对Web3技术的详细解析&#xff1a; 一、Web3技术的核心概念 Web3是第三代互联网技术的代名词&#xff0c;代表着去中心化、区块链驱动和用户自有控制的理念。在Web3的世界中…

景联文科技:专业数据采集标注公司 ,助力企业提升算法精度!

随着人工智能技术加速落地&#xff0c;高质量数据已成为驱动AI模型训练与优化的核心资源。据统计&#xff0c;全球AI数据服务市场规模预计2025年突破200亿美元&#xff0c;其中智能家居、智慧交通、医疗健康等数据需求占比超60%。作为国内领先的AI数据服务商&#xff0c;景联文…

3.【BUUCTF】XSS-Lab1

进入题目页面如下 好好好&#xff0c;提示点击图片&#xff0c;点进去页面如下&#xff0c;且url中有传参&#xff0c;有注入点 发现题目给出了源码 查看得到本题的源码 分析一下代码 <!DOCTYPE html><!--STATUS OK--> <!-- 声明文档类型为 HTML5&#xff0c;告…

进程、线程、内存和IO模型的概念详解

进程、线程、内存和IO模型的概念详解 1 进程与线程1.1 进程1.1.1 进程分类1.1.2 进程的状态和转换1.1.3 僵尸进程和孤儿进程的区别1.1.4 进程之间的通信1.1.5 用户态和内核态1.1.6 用户空间和内核空间 1.2 线程1.2.1 线程的状态和转换1.2.2 进程与线程的区别 1.3 多进程和多线程…

浅谈密码相关原理及代码实现

本代码仅供学习、研究、教育或合法用途。开发者明确声明其无意将该代码用于任何违法、犯罪或违反道德规范的行为。任何个人或组织在使用本代码时&#xff0c;需自行确保其行为符合所在国家或地区的法律法规。 开发者对任何因直接或间接使用该代码而导致的法律责任、经济损失或…

Swagger相关内容整合

mvc:pathmatch:matching-strategy: ant_path_matcher 一、引入相关依赖 <!-- 图像化依赖 --> <dependency><groupId>io.springfox</groupId><artifactId>springfox-swagger-ui</artifactId><version>2.9.2</version> </de…

【数据结构】循环链表

循环链表 单链表局限性单向循环链表判断链表是否有环思路code 找到链表入口思路代码结构与逻辑 code 单链表局限性 单链表作为一种基本的数据结构&#xff0c;虽然在很多场景下都非常有用&#xff0c;但它也存在一些局限性&#xff1a; 单向访问&#xff1a;由于每个节点仅包含…

简易C语言矩阵运算库

参考网址&#xff1a; 异想家纯C语言矩阵运算库 - Sandeepin - 博客园 这次比opencv快⑥倍&#xff01;&#xff01;&#xff01; 参考上述网址&#xff0c;整理了一下代码&#xff1a; //main.c#include <stdio.h> #include <stdlib.h> #include <string.h…

微服务知识——微服务架构的演进过程

文章目录 初始架构&#xff1a;单机架构第一次演进&#xff1a;Tomcat与数据库分开部署第二次演进&#xff1a;引入本地缓存和分布式缓存第三次演进&#xff1a;引入反向代理实现负载均衡第四次演进&#xff1a;数据库读写分离第五次演进&#xff1a;数据库按业务分库第六次演进…

Hackmyvm crack

简介 难度&#xff1a;简单 靶机地址&#xff1a; 环境 kali&#xff1a;192.168.194.9 靶机&#xff1a;192.168.194.23 扫描 nmap全端口扫描查看tcp服务 三个端口服务21的ftp服务、4200的shellinabox服务&#xff0c;是一个web界面的shell连接工具&#xff0c;12359的一…

P2036 [COCI 2008/2009 #2] PERKET(dfs)

#include<bits/stdc.h> using namespace std;int n; int a[15],b[15]; int ansINT_MAX; // 初始化最小差值为一个很大的数&#xff0c;保证能找到最小值void dfs(int i,int s,int k){if(in){ // 当遍历完所有元素时if(s1&&k0) return;int difabs(s-k);ans mi…

逻辑回归:Sigmoid函数在分类问题中的应用

欢迎来到我的主页&#xff1a;【Echo-Nie】 本篇文章收录于专栏【机器学习】 1 什么是Sigmoid函数&#xff1f; Sigmoid函数&#xff08;Logistic函数&#xff09;是机器学习中最经典的激活函数之一&#xff0c;是一个在生物学中常见的S型函数&#xff0c;也称为S型生长曲线。…

【OpenCV实战】基于 OpenCV 的多尺度与模板匹配目标跟踪设计与实现

文章目录 基于 OpenCV 的模板匹配目标跟踪设计与实现1. 摘要2. 系统概述3. 系统原理3.1 模板匹配的基本原理3.2 多尺度匹配 4. 逻辑流程4.1 系统初始化4.2 主循环4.3 逻辑流程图 5. 关键代码解析5.1 鼠标回调函数5.2 多尺度模板匹配 6. 系统优势与不足6.1 优势6.2 不足 7. 总结…

【系统架构设计师】操作系统 ② ( 存储管理 | 页式存储 | 逻辑地址 与 物理地址 | 页表结构 | 物理内存淘汰机制 )

文章目录 一、页式存储1、CPU 调用数据2、内存存储数据弊端3、分页存储4、逻辑地址 和 物理地址 的结构5、逻辑地址 和 物理地址 的结构 示例6、页式存储 优缺点 二、逻辑地址 与 物理地址1、逻辑地址2、物理地址3、逻辑地址 与 物理地址 区别4、逻辑地址 与 物理地址 的转换 三…

AMD数据中心业务创纪录,Instinct MI355X提前发布

没有人能预料到生成式人工智能&#xff08;GenAI&#xff09;会如此迅速地推动英伟达的扩张&#xff0c;也没有人能预料到英伟达的崛起和英特尔的衰落会如此之快。对于那些相信“第二名可以更努力并取得成功”的人来说&#xff0c;AMD的崛起无疑证明了这一点。然而&#xff0c;…

C++ 中的 `string` 类型:全面解析与高效操作

C 中的 string 类型&#xff1a;全面解析与高效操作 在 C 中&#xff0c;string 类型是对字符数组的高级封装&#xff0c;它提供了大量内置函数&#xff0c;使得字符串的处理变得更为简便和高效。与 C 风格的字符数组不同&#xff0c;string 类型不仅自动管理内存&#xff0c;…

穷举vs暴搜vs深搜vs回溯vs剪枝系列一>黄金矿工

目录 决策树&#xff1a;代码设计代码&#xff1a; 决策树&#xff1a; 代码设计 代码&#xff1a; class Solution {boolean[][] vis;int ret,m,n;public int getMaximumGold(int[][] grid) {m grid.length;n grid[0].length;vis new boolean[m][n]; for(int i 0; i <…

DeepSeek 的含金量还在上升

大家好啊&#xff0c;我是董董灿。 最近 DeepSeek 越来越火了。 网上有很多针对 DeepSeek 的推理测评&#xff0c;除此之外&#xff0c;也有很多人从技术的角度来探讨 DeepSeek 带给行业的影响。 比如今天就看到了一篇文章&#xff0c;探讨 DeepSeek 在使用 GPU 进行模型训练…