python初学者的行业分类器三部曲之二【GUI部分】

转载 不吃兔子的胡萝卜 2019/11/2 21:34:29

y初学者,想要做一个简单但是实用的小程序,实现目标如下:可以手动选择本地文件,然后点击确认后,生成一个“将不同行业放在不同”的新工作簿。从而免去每个月都需要在各个表格中反复匹配行业、反复筛选、反复复制粘贴到不同工作表的过程实现我“做一个轻松快乐、无忧无虑

python初学者,想要做一个简单但是实用的小程序,实现目标如下:

可以手动选择本地excel文件,然后点击确认后,生成一个“将不同行业放在不同sheet”的新工作簿。

从而免去每个月都需要在各个excel表格中反复匹配行业、反复筛选、反复复制粘贴到不同工作表的过程

实现我“做一个轻松快乐、无忧无虑、促甲状腺激素保持在正常水平的猿”的短期目标

进而可以有大把时间学习一下产业经济学等等内容

?

将目标做进一步分解:

1)首先用python写一段程序可以分行业

2)实现可以使用户手动选择文件的可能性

3)封装成exe

?

第二步:要实现用户手动选择excel文件的可能性

?

? ? a.上述过程是通过pandas包中read_excel实现的文件读取,想要手动选择,需要设计GUI,此处选了tkinter第三方库,

? ? ? ?tkinter的初步了解我参考了:

? ? ? ?【Python GUI之窗口视窗大集合(看这篇就够了)】https://blog.csdn.net/ahilll/article/details/81531587

? ? ? ?这篇博文系统地介绍了tkinter第三方库的主要参数等,读完感觉有点类似很久以前学的VB

? ? ? ?结合这部分内容,又参考了微信公众号的内容,把自己想要设计的窗体定义为三个部分:

? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 1)提示文本:用来提示用户选择的文件应当是包含行业代码字段的excel文件
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 2)选择文件的部分:(最主要的内容)
? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 3)确认按钮:点击按钮后弹出提示框:已完成或者报错(如果不是excel文件或者文件不包含行业代码字段就报错)

?

? ? ?b.但是上面的博客并没有介绍如何让用户手动选择文件,为了解决这个问题,参考了:

? ? ? ?【tkinter让用户选择文件并返回可读取文件绝对地址】https://blog.csdn.net/qq_44239466/article/details/90250938

? ? ? ?这个链接只解决我如何使用户可以读取文件的问题,还不清楚如何得到选取文件的绝对地址,为了解决这个问题,参考了:

? ? ? ?【python文件选择tkinter.filedialog的使用】https://segmentfault.com/q/1010000005048090

? ? ? ?在评论中作者给出的解决办法是,需要在函数中定义全局变量

? ? ? ?结合前面那个问题,可以把path设置成全局变量,就可以得到文件路径,结合pandas中的read_excel函数,可以把这部分和1)b结合起来了

?

? ? ?c.参考b步骤里的两个链接,实现了选择文件并读取的问题,接下来要做的就是确认按钮的设计

? ? ? ?这个步骤可以参考【tkinter让用户选择文件并返回可读取文件绝对地址】在tk上添加buttom,并把它关联一个别的函数

? ? ? ?所要做的就是定义一个用来检测是否出现异常的函数,包含功能:

? ? ? ? ? ? ?判断读取的是否是excel文件,不是则报错,也就是str(path)中是否包含xlsx字符串,如果不是excel文件,则不执行分类操作

? ? ? ? ? ? ?判断文件是否包含目标字段,不是则报错,如果文件不包含目标字段,同样退出执行分类操作

? ? ? ? ? ? ?嵩天教材的118页提供了一种异常处理的办法,为了使用这种办法,随便读取一个不相关的文件

? ? ? ? ? ? ?得出python将想要检测的第二种异常定义为keyError

? ? ? ? ? ? ?这部分可能需要把 1)b 中的代码作为一个函数,放在这个检测异常的函数中

?

? ? ? d.上述内容还没有考虑到:如果有人没有选择文件就点击按钮二怎么办?这时path变量是不存在的啊。

? ? ? ? ?可以把这一点考虑在上面异常处理的步骤里,但是还是忍不住要想:能不能设置成没有选择文件的时候按钮二是灰色禁止点击呢?

? ? ? ? ?只是想做一个简单的小程序而已,没想到这么复杂了……

? ? ? ? ?其实上面那个“所选择的文件不是excel文件”的异常,还想让用户只能选择excel文件(看不到excel文件以外的其他文件)来着

? ? ? ? ?但是时间关系,还是做异常处理吧,这种异常是NameError

? ? ? ? ?画出这部分的流程图如下:(在纸上呢)

? ? ? ? ?这时主函数,也就是点击按钮二调用的函数:

def mainFunc():
    try:
        if "xls" in str(path_):
            classify()
        else:
            print("请检查所选择的文件是否是excel文件")
    except NameError:
            print("请检查是否选择了文件")

? ? ? ? ?如果是excel文件,则调用分类器函数:

def classify():
    try:
        #步骤0:读取目标文件并给目标文件加上行业标签:
        data = pd.read_excel(str(path_)) #没有选择文件会产生异常 NameError
        industry_rule = pd.read_excel('/Users/Desktop/行业代码-2017.xlsx') #因为目标文件没有b103b17字段 KeyError
        data = pd.merge(data,industry_rule.loc[:,['b103b17','门类名称']],how='left',on = 'b103b17')

        #步骤1:得到目标文件中所有包含的行业门类(为了避免产生冗余工作表,不生成全部行业,只生成有的那些)
        rows = data.shape[0]  #获取行数 shape[1]获取列数
        industry_list = []  #新建空列表,用来存放行业分类
        for i in range(rows):
            temp = data["门类名称"][i]
            if temp not in industry_list:    #防止重复
                industry_list.append(temp)   #将行业分类存在一个列表中

        #步骤2:按照行业类别生成一个个数据框
        n = len(industry_list)    #数据所包含的行业数
        df_list=[]
        for i in range(n):
            df_one = pd.DataFrame()
            df_list.append(df_one)

        #步骤3:遍历所有企业,将它们放在指定的工作表中
        for industry in range(n):
            for i in range (0, rows):
                if data["门类名称"][i] == industry_list[industry]:
                    df_list[industry] = pd.concat([df_list[industry], data.iloc[[i],:]], axis = 0, ignore_index = True)

        #步骤4:写出文件(想要原文件名加分行业几个字导出)    
        writer = pd.ExcelWriter('/Users/yuan/Desktop/分行业.xls')    #利用pd.ExcelWriter()存多张sheets
        for i in range(n):
            df_list[i].to_excel(writer, sheet_name = str(industry_list[i]), index=False)    #注意加上index=FALSE 去掉index列
        writer.save()
        
    except KeyError:
        print("目标文件不包含b103b17字段,请重新选择文件")
    except:
        print("出现其他异常")

?

?

? ? ? e.另外还想实现一点就是把生成的新文件保存在用户选择的那个路径,文件名在原文件名后面加三个字“分行业”:

? ? ? ? (其实加在前面更容易,但加在后面呢可以使两个文件默认在一起嘛)

? ? ? ? 之前在步骤一中是编辑了桌面路径的:

writer = pd.ExcelWriter('/Users/Desktop/分行业.xls')    #利用pd.ExcelWriter()存多张sheets

? ? ? ? 只需要修改为:在原路径的后缀.xlsx前面加几个字符

writer = pd.ExcelWriter("".join([str(path_).split(".")[0],"(分行业).",str(path_).split(".")[1]]))

? ? ???

? ? ? ? f.再者,之前的错误提示是用print提示语替代的,如果可以,想把它变成在窗体上显示的形式

? ? ? ? ?是不是直接把print语句换成tk.Label就可以呢?一试果然如此,这个问题就这么轻而易举解决啦

? ? ? ? ?注意生成的label另起一行不然会覆盖

? ? ? ??

? ? ?

?

?

?

?

?

上一篇:用最复杂的方式学会数组(Python实现动态数组)

下一篇:一起来刷《剑指Offer》——不修改数组找出重复的数字(思路及Python实现)

赞(0)

共有 条评论 网友评论

验证码: 看不清楚?
    IT文章导航
    扫一扫关注最新编程为什么上不了bet356_bet356 下载安装_bet356黑钱