赞
踩
目录
本地简单数据分析平台
一、题目描述
当今社会中统计学、大数据分析等已经成为无论文理的各个学科中必要的研究途径以及
展示数据最好的形式,其便捷性及强大的功能也是各个软件所追求的目标之一。
选择本题,你需要完成一个程序,包含一个 GUI 的界面,能够清晰地引导用户导入数
据文件,并且给出至少两种数据分析及展示方法,最后能够将结果导出为用户指定的格
式。
二、基本实验要求
本题你必须给出一个 GUI 界面,需要清晰直观地给出导入和导出文件的按钮,在导入
文件之后能够给出数种可以进行一键分析的按钮。
根据用户选择的分析方法,需要自动检测导入的数据是否符合要求(例如单变量数据不
能够进行相关分析),并给出相应的提醒或者是报错信息。
展示方法中可以由用户自定义横纵坐标刻度、标题以及图例外观等相关参数,支持双变
量做图等功能,导出前可以由弹窗等形式进行预览。
三、必做部分
你的程序必须有一个 GUI 页面,要求简洁美观,能够一键完成用户所需的操作:
(1)
导入数据文件。基础的单变量数据文件规定为一个 n+1 行两列的 csv 文件。
其中包含 n 个数据,例如下表:
要求 n 不小于 100,数据的来源可以根据自己的专业喜好来选择,可以但不限于
从以下网站获取:
a) 国家统计局:http://data.stats.gov.cn/index.htm
b) Science Data Bank:http://www.sciencedb.cn/index导入的方式可以是直接从当前目录读取特定名称的 csv 文件,也可以给出一个文
本框,由用户输入文件名。
(2) 开展数据分析,必须能够至少输出包括最基本的描述统计量(平均数,中位
数,众数等)。
在导入数据后,应给出相应的数据分析按钮,用户点击后应显示出分析结果。
(3) 对于描述统计结果可视化,必须包括以下两种方式:
a) 柱状图
b) 折线图
(4) 将 Matplotlib 可视化结果可以用弹窗进行预览,并且导出保存,图片格式为
png 格式。保存的位置任意。
四、选做部分
以下内容非必做项,每完成一条选做项,都可以给大作业带来额外的加分,你同样可
以用其他额外的内容来丰富你的大作业,以获得加分。以下为提供的一些思路和方向。
(1)在导入数据方面,支持更多的文件格式和数据文件内容,比如 json、xls 文件,多
变量数据等。
(2)在数据分析方面,添加更多的方法,可以包括但不限于:
a) 广义线性模型
b) 非参数检验
(3)在做图方面,支持更多的做图类型,例如饼图等,支持用户自己定义图例,图线
颜色、标题等。对于多变量的数据,可以进行多线图等多变量的图形绘制。
(4)在 GUI 方面,能够将导入的数据使用表格进行展示。
(5)在用户选择了分析方法后,可以自动检测导入的数据是否符合要求(例如单变量
数据不能够进行相关分析),并给出相应的提醒或者是报错信息。
(6)导出时,你可以利用 Markdown 文本,将数据与分析结果进行整合,最后生成一
份详细的数据报告。
以上选做部分不要求全部完成,也不必局限于给出的这些内容
-
- from tkinter import* #导入会用上的库
- import tkinter.messagebox
- from tkinter.messagebox import*
- from PyQt5.QtWidgets import (QWidget, QToolTip, QDesktopWidget, QMessageBox,QTextEdit,QLabel,
- QPushButton, QApplication,QMainWindow, QAction, qApp, QHBoxLayout, QVBoxLayout,QGridLayout,
- QLineEdit) #这是PyQt5最主要的模块
- from PyQt5 import QtWidgets
- import sys
- from PyQt5.QtGui import QFont,QIcon
- from PyQt5.QtWidgets import QApplication, QWidget
- from PyQt5.QtCore import QCoreApplication
- import pandas as pd #数据分析用的pandas库
- from scipy import stats #stats也是数据分析用的
- import matplotlib.pyplot as plt
- plt.rcParams['font.sans-serif']=['SimHei'] #用于正常显示中文
-
- top=Tk() #Tk()是创建窗口
- top.title("文件分析窗口1")
- label1=Label(top,text="请输入要分析的文件名")
- un_textbox=Text(top,height=1,width=20) #定义了一个文本框
- enter_button=Button(top,text="开始",command=lambda:enter()) #定义了一个按钮
- def enter(): #这个回调函数可以提取出文本框输入的内容,并且可以销毁文本框
- global file_path #将file_path设为全局变量,之后提取文件都会用上它
- name=un_textbox.get(1.0,END)
- file_path =name[0:-1]
- top.destroy()
- un_textbox.grid(row=0,column=1) #用grid进行布局
- label1.grid(row=0,sticky=W)
- enter_button.grid(row=2,column=0,padx=5,pady=5)
- top.mainloop()
-
- def load_data1(qaction): #这是我们定义的一个与导入数据有关的回调函数
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float) #df为读入的数据
- num=df.columns.size #num为有效的,可以进行分析的数据列数
- if num==1: #如果数据满足条件,就会弹出"导入文件数据成功!"的GUI窗口提示
- top=Tk()
- top.title("恭喜你!!!")
- label1=Label(top,text="导入文件数据成功!")
- def enter1():
- top.destroy()
- cl_button=Button(top,text="关闭",command=lambda:enter1())
- label1.pack()
- cl_button.pack()
- top.mainloop()
- print('导入文件数据成功!')
- else : #如果不满足条件,就会弹出"导入文件数据失败!"的GUI窗口提示
- top=Tk()
- top.title("不好意思!")
- label2=Label(top,text="导入文件数据失败,你的数据不符合格式!")
- def enter2():
- top.destroy()
- cl_button=Button(top,text="关闭",command=lambda:enter2())
- label2.pack()
- cl_button.pack()
- top.mainloop()
- print('导入文件数据失败!')
-
- def d1(df): #d1回调函数,打印出中位数
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- #df.quantile(q=0.5)[0])为pandas库里面计算中位数的方法
- print('第二列数据中位数的值为:' + str(df.quantile(q=0.5)[0]) )
- def d2(df): #d2回调函数,打印出众数
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- #利用stats库来计算了众数
- print('第二列数据众数的值为:' + str(stats.mode(df)[0][0][0]) )
- def d3(df): #d3回调函数,可以打印出所有的统计量值
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- #dataframe.describe(),可以对数据进行全面分析
- s = df.describe()
- st = list(s.values[:,0])
- st_index = list(s.index.values)
- st_index.append('中位数')
- st.append( df.quantile(q=0.5)[0] )
- st_index.append('众数')
- st.append( stats.mode(df)[0][0][0] )
- r = pd.DataFrame(st,columns=['注:count表示统计数据的数量,mean表示平均数,std表示标准差,min表示最小值,max表示最大值'])
- r.index = st_index
- print('所有统计量如下:')
- print(r)
- def d4(df): #d4回调函数,可以打印出平均值
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- #先用describe函数计算全部统计值,然后再切片出平均数
- s = df.describe()
- st = list(s.values[:,0])
- mean1=st[1]
- print(st)
- print("第二列数据平均值为:",mean1)
-
-
-
-
- def pie(): #pie()用来绘制饼图,我们可以自定义要绘制的列数
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- y=eval(input("绘制的数据列数:"))
- df=df[0:y+1]
- print(df) #df就是最后选择的行数后的dataframe数据
- df.plot(kind="pie",subplots=True) #用dataframe.plot绘图
- plt.show()
- u=input("是否保存图片:")
- if u in "是":
- plt.savefig("pie.png")
- def bar(): #bar()函数用来绘制柱状图,可选参数有:“是否保存图片
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- s = df.describe()
- st = list(s.values[:,0])
- st_index = list(s.index.values)
- st_index.append('中值')
- st.append( df.quantile(q=0.5)[0] )
- st_index.append('众数')
- st.append( stats.mode(df)[0][0][0] )
- r = pd.DataFrame(st,columns=['统计量值'])
- r.index = st_index #r即为最后要绘制的数据
- print(r)
- r.plot(kind="bar")
- plt.show()
- u=input("是否保存图片:")
- if u in "是":
- plt.savefig("bar.png")
- def plot():#plot()函数用来绘制折线图,可选参数有;“绘制数据的行数”“x轴标签,
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- y=eval(input("绘制的数据列数:"))
- df=df[0:y+1]
- print(df)
- a=input("请输入x轴标签:")
- b=input("请输入y轴标签:")
- c=input("请输入标题:")
- d=input("折线的颜色:")
- print("将自动根据数据调整x轴,y轴坐标")
- plt.xlabel(a)
- plt.ylabel(b)
- plt.title(c)
- plt.plot(df,color=d)
- plt.show()
- u=input("是否保存图片:")
- if u in "是":
- plt.savefig("plot.png")
-
-
-
-
- def output_csv(): #output_csv()函数可以将数据导出为csv后缀形式
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- df.to_csv(file_path.replace('.xlsx','') + '.csv',header=True,index=True) #默认写入index
- print('导出csv数据成功')
- def output_json(): #output_json()函数可以将数据导出为csv后缀形式
- df = pd.read_excel(file_path,header=0,index_col=0)
- df = df.astype(float)
- df.to_json(file_path.replace('.xlsx','') + '.json')
- print('导出json数据成功')
-
- #用class MenuBar(QMainWindow)函数,创建一个程序窗口,在这个程序窗口可以有各种操作。
- class MenuBar(QMainWindow):
- def __init__(a):
- super().__init__()
- #menubar是创建一个菜单栏,之后我们会将不同的多选按钮放进去
- menubar = a.menuBar()
- #fileMenu1是我们定义的一个菜单里的多选按钮,主按钮为“文件导入与导出”,多选按钮为“导入数据”“导出csv数据”“导出json数据”,这三个按钮对应了之前定义的三个回调函数,进而实现功能。
- fileMenu1 = menubar.addMenu('&文件导入与导出')
- load_data=QAction("导入数据",a)
- load_data.triggered.connect(load_data1)
- fileMenu1.addAction(load_data)
- output_data1=QAction("导出csv数据",a)
- output_data1.triggered.connect(output_csv)
- fileMenu1.addAction(output_data1)
- output_data2=QAction("导出json数据",a)
- output_data2.triggered.connect(output_json)
- fileMenu1.addAction(output_data2)
- #fileMenu2是我们定义的一个菜单里的多选按钮,主按钮为“数据分析”,多选按钮为“中位数”“众数”“平均数”“全部统计量”,这四个按钮对应了之前定义的四个回调函数,进而实现功能。
- fileMenu2 = menubar.addMenu('&数据分析')
- median=QAction("中位数",a)
- median.triggered.connect(d1 )
- fileMenu2.addAction(median)
- zhongshu=QAction("众数",a)
- zhongshu.triggered.connect(d2 )
- fileMenu2.addAction(zhongshu)
- mean2=QAction("平均数",a)
- mean2.triggered.connect(d4)
- fileMenu2.addAction(mean2)
- alls=QAction("全部统计量",a)
- alls.triggered.connect(d3 )
- fileMenu2.addAction(alls)
- #fileMenu3是我们定义的一个菜单里的多选按钮,主按钮为“作图”,多选按钮为“柱状图”“折线图”“饼图”,这三个按钮对应了之前定义的三个回调函数,进而实现功能。
- fileMenu3 = menubar.addMenu('&作图')
- barpng=QAction("柱状图(对统计量值)",a)
- barpng.triggered.connect(bar)
- fileMenu3.addAction(barpng)
- plotpng=QAction("折线图",a)
- plotpng.triggered.connect(plot)
- fileMenu3.addAction(plotpng)
- piepng=QAction("饼图",a)
- piepng.triggered.connect(pie)
- fileMenu3.addAction(piepng)
- #对GUI窗口的大小,标签进行设置
- a.setGeometry(400, 400, 400, 400)
- a.setWindowTitle('文件分析窗口2')
- a.show()
-
- #让程序循环运行
- if __name__ == '__main__':
- df = []
- app = QApplication(sys.argv)
- ex = MenuBar()
- sys.exit(app.exec_())
-
-
-
-
-
-
-
描述通过本题目的实现将考察哪些知识点和方法。
这道题考察很多方面的知识。首先最主要考察的是GUI界面的创建。对于GUI界面的创建,我使用了两个库,一个是Tkinter(运用了其中大量的参数),还有一个是PyQt5(运用了里面一个多选函数按钮)。其中Tkinter我们在之前的学习过程中已经学过,并且通过上机训练熟练掌握了。这次我想尝试一下新鲜事物,所以我的程序主要的GUI都是由PyQt5来实现。这里运用了大量PyQt5的知识。其次,由于要对数据进行分析,所以用Pandas对数据进行处理,其中大量运用dataframe数据现形式。作图方面,我使用了Matplotlib函数进行图像绘制,同时还使用了dataframe.plot()形式进行绘图。同时我还使用了scipy里面的stats库。
这考察了我们对一个最为简单的GUI程序的设计,需要我们有大局观,能够合理布局,在不同时候弹出不同的窗口。
描述本题目需要完成的内容和要求。
要求有GUI 界面,需要有导入和导出文件的按钮,在导入文件之后能够对数据的不同统计量值进行一键分析,并且打印相应的统计值。
如果数据不满足条件进行报错。同时我们还可以对数据导出为csv,json等不同形式的按钮。
对于数据本身和分析后的统计量值可以根据需求进行不同类型的图形绘制,可视化时我们可以对参数(如标题,折线颜色等)进行自定义,选择是否保存图片。
介绍作业完成的功能,实现方案(如程序分为几部分,每部分采用什么方法、解决什么问题)。
程序可以分为7个部分,从上到下
注:每个部分的具体的函数解释在下面的“四、设计思路和关键语法”
注意:这是本报告的重点!
详细分析实验的实现方法,介绍你的设计用到了哪些函数或者涉及哪些知识点;详述每个模块的关键语法及其实现。
#创建了一个窗口,让用户输入需要导入的数据文件的名称。这一部分的GUI我主要使用Tkinter进行实现。主要是用Tk()创建窗口,然后用Text定义文本框,然后定义一个按钮(使用get函数)可以提取文本框输入的内容。grid函数进行界面布局
top=Tk() #Tk是创建窗口
top.title("文件分析窗口1")
label1=Label(top,text="请输入要分析的文件名")
un_textbox=Text(top,height=1,width=20) #定义了一个文本框
enter_button=Button(top,text="开始",command=lambda:enter()) #定义了一个按钮
def enter(): #这个回调函数可以提取出文本框输入的内容,并且可以销毁文本框
global file_path #将file_path设为全局变量,之后提取文件都会用上它
name=un_textbox.get(1.0,END)
file_path =name[0:-1]
top.destroy()
un_textbox.grid(row=0,column=1) #用grid进行布局
label1.grid(row=0,sticky=W)
enter_button.grid(row=2,column=0,padx=5,pady=5)
top.mainloop()
#定义了一个导入数据的load_data1(qaction)函数,其中如果数据满足条件就弹出成功的窗口,如果不满足条件就会弹出一个窗口
#主要使用Tkinter库来进行界面的GUI,参数与第一部分大概相同,columns.size来获取有效行数并且进行比对,从而进行判断数据是否满足条件。(有一个if判断语句)
def load_data1(qaction): #这是我们定义的一个与导入数据有关的回调函数
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float) #df为读入的数据
num=df.columns.size #num为有效的,可以进行分析的数据列数
if num==1: #如果数据满足条件,就会弹出"导入文件数据成功!"的GUI窗口提示
top=Tk()
top.title("恭喜你!!!")
label1=Label(top,text="导入文件数据成功!")
def enter1():
top.destroy()
cl_button=Button(top,text="关闭",command=lambda:enter1())
label1.pack()
cl_button.pack()
top.mainloop()
print('导入文件数据成功!')
else : #如果不满足条件,就会弹出"导入文件数据失败!"的GUI窗口提示
top=Tk()
top.title("不好意思!")
label2=Label(top,text="导入文件数据失败,你的数据不符合格式!")
def enter2():
top.destroy()
cl_button=Button(top,text="关闭",command=lambda:enter2())
label2.pack()
cl_button.pack()
top.mainloop()
print('导入文件数据失败!')
#这一部分主要是使用pandas库,利用pandas库的内置函数对dataframe数据进行处理,(众数,平均数,中位数,最小数,最大数等)
def d1(df): #d1回调函数,打印出中位数
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
#df.quantile(q=0.5)[0])为pandas库里面计算中位数的方法
print('第二列数据中位数的值为:' + str(df.quantile(q=0.5)[0]) )
def d2(df): #d2回调函数,打印出众数
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
#利用stats库来计算了众数
print('第二列数据众数的值为:' + str(stats.mode(df)[0][0][0]) )
def d3(df): #d3回调函数,可以打印出所有的统计量值
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
#dataframe.describe(),可以对数据进行全面分析
s = df.describe()
st = list(s.values[:,0])
st_index = list(s.index.values)
st_index.append('中位数')
st.append( df.quantile(q=0.5)[0] )
st_index.append('众数')
st.append( stats.mode(df)[0][0][0] )
r = pd.DataFrame(st,columns=['注:count表示统计数据的数量,mean表示平均数,std表示标准差,min表示最小值,max表示最大值'])
r.index = st_index
print('所有统计量如下:')
print(r)
def d4(df): #d4回调函数,可以打印出平均值
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
#先用describe函数计算全部统计值,然后再切片出平均数
s = df.describe()
st = list(s.values[:,0])
mean1=st[1]
print(st)
print("第二列数据平均值为:",mean1)
#根据数据绘图部分,定义了三个函数,分别绘制饼图,柱状图,折线图。我先使用pandas来处理数据,进而有的使用Matplotlib,有的使用dataframe.plot()来绘制
def pie(): #pie()用来绘制饼图,我们可以自定义要绘制的列数
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
y=eval(input("绘制的数据列数:"))
df=df[0:y+1]
print(df) #df就是最后选择的行数后的dataframe数据
df.plot(kind="pie",subplots=True) #用dataframe.plot绘图
plt.show()
u=input("是否保存图片:")
if u in "是":
plt.savefig("pie.png")
def bar(): #bar()函数用来绘制柱状图,可选参数有:“是否保存图片
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
s = df.describe()
st = list(s.values[:,0])
st_index = list(s.index.values)
st_index.append('中值')
st.append( df.quantile(q=0.5)[0] )
st_index.append('众数')
st.append( stats.mode(df)[0][0][0] )
r = pd.DataFrame(st,columns=['统计量值'])
r.index = st_index #r即为最后要绘制的数据
print(r)
r.plot(kind="bar")
plt.show()
u=input("是否保存图片:")
if u in "是":
plt.savefig("bar.png")
def plot():#plot()函数用来绘制折线图,可选参数有;“绘制数据的行数”“x轴标签,
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
y=eval(input("绘制的数据列数:"))
df=df[0:y+1]
print(df)
a=input("请输入x轴标签:")
b=input("请输入y轴标签:")
c=input("请输入标题:")
d=input("折线的颜色:")
print("将自动根据数据调整x轴,y轴坐标")
plt.xlabel(a)
plt.ylabel(b)
plt.title(c)
plt.plot(df,color=d)
plt.show()
u=input("是否保存图片:")
if u in "是":
plt.savefig("plot.png")
#定义了两个函数,主要功能是将数据进行不同形式导出。使用替换后缀的方法转化为不同格式
def output_csv(): #output_csv()函数可以将数据导出为csv后缀形式
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
df.to_csv(file_path.replace('.xlsx','') + '.csv',header=True,index=True) #默认写入index
print('导出csv数据成功')
def output_json(): #output_json()函数可以将数据导出为csv后缀形式
df = pd.read_excel(file_path,header=0,index_col=0)
df = df.astype(float)
df.to_json(file_path.replace('.xlsx','') + '.json')
print('导出json数据成功')
#这一部分,我主要是使用PyQt5库里面的模板,进行多选函数按钮的调用
#用class MenuBar(QMainWindow)函数,创建一个程序窗口,在这个程序窗口可以有各种操作。
class MenuBar(QMainWindow):
def __init__(a):
super().__init__()
#menubar是创建一个菜单栏,之后我们会将不同的多选按钮放进去
menubar = a.menuBar()
#fileMenu1是我们定义的一个菜单里的多选按钮,主按钮为“文件导入与导出”,多选按钮为“导入数据”“导出csv数据”“导出json数据”,这三个按钮对应了之前定义的三个回调函数,进而实现功能。
fileMenu1 = menubar.addMenu('&文件导入与导出')
load_data=QAction("导入数据",a)
load_data.triggered.connect(load_data1)
fileMenu1.addAction(load_data)
output_data1=QAction("导出csv数据",a)
output_data1.triggered.connect(output_csv)
fileMenu1.addAction(output_data1)
output_data2=QAction("导出json数据",a)
output_data2.triggered.connect(output_json)
fileMenu1.addAction(output_data2)
#fileMenu2是我们定义的一个菜单里的多选按钮,主按钮为“数据分析”,多选按钮为“中位数”“众数”“平均数”“全部统计量”,这四个按钮对应了之前定义的四个回调函数,进而实现功能。
fileMenu2 = menubar.addMenu('&数据分析')
median=QAction("中位数",a)
median.triggered.connect(d1 )
fileMenu2.addAction(median)
zhongshu=QAction("众数",a)
zhongshu.triggered.connect(d2 )
fileMenu2.addAction(zhongshu)
mean2=QAction("平均数",a)
mean2.triggered.connect(d4)
fileMenu2.addAction(mean2)
alls=QAction("全部统计量",a)
alls.triggered.connect(d3 )
fileMenu2.addAction(alls)
#fileMenu3是我们定义的一个菜单里的多选按钮,主按钮为“作图”,多选按钮为“柱状图”“折线图”“饼图”,这三个按钮对应了之前定义的三个回调函数,进而实现功能。
fileMenu3 = menubar.addMenu('&作图')
barpng=QAction("柱状图(对统计量值)",a)
barpng.triggered.connect(bar)
fileMenu3.addAction(barpng)
plotpng=QAction("折线图",a)
plotpng.triggered.connect(plot)
fileMenu3.addAction(plotpng)
piepng=QAction("饼图",a)
piepng.triggered.connect(pie)
fileMenu3.addAction(piepng)
#对GUI窗口的大小,标签进行设置
a.setGeometry(400, 400, 400, 400)
a.setWindowTitle('文件分析窗口2')
a.show()
说明你采用了什么独特的方法或者课堂介绍方法之外的方法来解决某个问题;增加了哪些功能;介绍你设计的亮点在于什么地方。
1、在本实验中你遇到了哪些问题?是如何解决的?
说明:除了用文字阐述外,最好给出改进前后的源代码。
df.to_csv(file_path.replace('.xlsx','') + '.csv',header=True,index=True)
u=input("是否保存图片:")
if u in "是":
plt.savefig("pie.png")
收获:最大的收获是学会了用PyQt5进行窗口布局,会用了PyQt5库里面的模板。还会了pandas里面的函数。
原来很多看起来很复杂的问题。我们只要把它们进行分解,分成很多小问题进行解决就能一一攻破。
其他角度:对一些游戏进行改编,比如设计一些可以操纵人物移动的小游戏。又或者是数独,拼图这样的游戏。
大量csdn文章
《Python速查手册》,北京希望电子出版社
《Python语言程序设计基础》,嵩天,高等教育出版社
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。