如何将SQL查询结果转换为适配Pandas绘图的格式?
问题
我正在开发Python项目,通过pyodbc从Microsoft SQL Server数据库获取数据,再用Pandas生成柱状图,但因数据库返回的数组格式问题无法正常运行。
当前查询代码
# Import Modules import pandas as pd # Graph Module import pyodbc # Microsoft SQL Server Module # Connection string conn_str = ( "DRIVER={SQL Server Native Client 11.0};" "SERVER=server,port;" "DATABASE=db;" "UID=user;" "PWD=pass;" ) conn = pyodbc.connect(conn_str) cursor = conn.cursor() cursor.execute("SELECT DISTINCT processname AS 'Proces Naam' FROM table WHERE status = 'Aborted' ORDER BY processname ASC") result = cursor.fetchall() print(result)
当前查询输出
[('proces1', ), ('proces2', ), ('proces3', ), ('proces4', ), ('proces5', ), ('proces6', ), ('proces7', )]
期望的数组格式
['proces1','proces2','proces3','proces4','proces5','proces6','proces7']
绘图代码及报错
尝试用以下代码绘图时出现错误:
# Set Dataset dataset={ 'PROCESS':[result], 'ABORTS':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] # 占位数据,查询结果共17条进程名 } # Create Graph df = pd.DataFrame(data=dataset) df.plot.bar(title="Aborts", x='PROCESS')
报错信息:
"name": "ValueError", "message": "arrays must all be same length",
解决方案
方法一:直接用Pandas读取SQL查询结果(最简便)
无需手动处理fetchall()的结果,直接通过pd.read_sql()从数据库连接读取数据并生成DataFrame,后续绘图流程更顺畅:
import pandas as pd import pyodbc conn_str = ( "DRIVER={SQL Server Native Client 11.0};" "SERVER=server,port;" "DATABASE=db;" "UID=user;" "PWD=pass;" ) conn = pyodbc.connect(conn_str) # 直接读取查询结果到DataFrame df = pd.read_sql("SELECT DISTINCT processname AS 'PROCESS' FROM table WHERE status = 'Aborted' ORDER BY processname ASC", conn) # 添加ABORTS列(注意数据长度需与PROCESS列一致) df['ABORTS'] = [1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] # 生成柱状图 df.plot.bar(title="Aborts", x='PROCESS')
方法二:手动处理fetchall()的结果
如果需要保留cursor查询的方式,可将fetchall()返回的元组列表转换为字符串列表:
# 提取每个元组的第一个元素,生成目标格式的列表 process_list = [item[0] for item in result] # 构建数据集时直接传入处理后的列表,避免长度不匹配 dataset={ 'PROCESS': process_list, 'ABORTS':[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17] } df = pd.DataFrame(data=dataset) df.plot.bar(title="Aborts", x='PROCESS')
错误原因说明
之前的报错是因为dataset['PROCESS'] = [result]将整个元组列表作为单个元素传入,导致PROCESS列仅1个元素,而ABORTS列有17个元素,两列长度不匹配。正确做法是直接传入处理后的字符串列表,确保两列长度一致。
内容的提问来源于stack exchange,提问作者Stefan Meeuwessen
相关产品推荐
相关产品推荐

