ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

python生成Excel透视表

2021-10-04 11:30:22  阅读:173  来源: 互联网

标签:right python 透视 frame Excel tk import left pack


        假设你有如下数据,

姓名科目成绩
小黑语文42
小娜语文23
小白语文98
小乐语文52
小黑数学30
小娜数学76
小白数学47
小乐数学73
小黑英语63
小娜英语83
小白英语4
小乐英语71

        想生成一个透视表,你肯定要去Excel工具里面操作,但是呢,数据多了可能会出错,所以我们可以借助python提供的 pandas 模块进行透视表生成。

        视频演示

<iframe allowfullscreen="true" data-mediaembed="bilibili" id="9onWQi8p-1633317518963" src="https://player.bilibili.com/player.html?aid=805960833&page=1"></iframe>

python透视表 生成演示

        话不多说,我们先来看看生成后表格的数据项:

        如上就是pandas生成的 Excel透视表,数据一目了然,看的非常清楚直观,前面两行和第四行是代码生成、便于拥有多个数据时进行区分的,如不需要,可进行删除,ALL是成绩的总和。

下面开始上代码教程

        这个工具是用Tkinter模块开发的,所以先导入Tkinter相关模块。

import tkinter as tk
import tkinter.font as tkFont
from tkinter.filedialog import askdirectory
import tkinter.messagebox
import tkinter.filedialog

        对于Tkinter图形界面详细开发教程这里就不多说,可自行百度。或者可查看

Python GUI之tkinter窗口视窗教程大集合

         还有一些其他的模块也一并导入


import os
import pandas as pd
import numpy as np
from pylab import mpl
from matplotlib import pyplot as plt

import tkinter as tk
import tkinter.font as tkFont
from tkinter.filedialog import askdirectory
import tkinter.messagebox
import tkinter.filedialog

         然后新建一个GUI界面,并在GUI界面添加如下操作元素:两个输入框和两个按钮,分别用来选择需要操作的Excel表和选择保存的文件夹。还有另外三个输入框与按钮,分别用来选择显示在透视表左边和透视表上方的数据项,以及需要比较的数据项,最后是一个清除输入框内容的按钮和一个生成文件的按钮。

        示例图如下:

        上方的图表功能这篇文章暂不讨论,下次再拿出来分享。 

         好了,现在开始放代码

import os
import pandas as pd
import numpy as np
import tkinter as tk
import tkinter.font as tkFont
from tkinter.filedialog import askdirectory
import tkinter.messagebox
import tkinter.filedialog
from pylab import mpl
from matplotlib import pyplot as plt
#制作图表时,需要加入这段代码,不然生成的图标会乱码
mpl.rcParams['font.sans-serif'] = ['Microsoft YaHei']

window = tk.Tk()
window.title('透视表生成(通用版)')
# 获取屏幕宽高
sw = window.winfo_screenwidth()
sh = window.winfo_screenheight()
# 设置屏幕的宽和高
ww = 600
wh = 500
x = (sw - ww) / 2
y = (sh - wh) / 2
# 根据屏幕宽高来让程序居中
window.geometry("%dx%d+%d+%d" % (ww, wh, x, y))
window.resizable(width=False, height=False)
# 设置字体
fontStyle = tkFont.Font(family="Lucida Grande", size=15)
fontStyleRadio = tkFont.Font(family="Lucida Grande", size=13)
# 应用标题
tk.Label(window, text="透视表生成(通用版)", font=fontStyle).pack()
dataState = ""

ty = "0"
def askd():
    if ty == "1":
        tks2()
    global paths
    # 打开文件 设置只能打开xls和xlsx文件
    paths = tkinter.filedialog.askopenfilename(title='打开表格', filetypes=[("xlsx", ".xlsx"), ("xls", ".xls")])
    path.set(paths)
    cc = paths.endswith(".xls")
    # 进行表格数据读取,将第一行数据放入Listbox中进行后续选择
    if cc == True:
        df = pd.read_excel(paths)
    else:
        df = pd.read_excel(paths, engine='openpyxl')
    labels = list(df.columns)
    global lb
    lb = tk.Listbox(window, font=fontStyle)
    for ite in labels:
        lb.insert('end', ite)
    lb.pack()
    print(paths)
    tks()

# 如果第二次选择表格,就将ty设置为1,当ty=1时,清空 Listbox 的数据
def tks():
    global ty
    ty = "1"
def tks2():
    lb.destroy()

index__ = []
# 左边的数值
def lbs1():
    tPath1.set(tPath1.get() + lb.get(lb.curselection()) + "、")
    index__.append(lb.get(lb.curselection()))
# 顶部的数值
def lbs2():
    tPath2.set(lb.get(lb.curselection()))

global values_
values2_ = []
# 要比较的数据
def lbs3():
    tPath3.set(tPath3.get() + lb.get(lb.curselection()) + "、")
    values2_.append(lb.get(lb.curselection()))

# 选择要保存的文件夹
def askd2():
    global paths2
    paths2 = askdirectory() + "/"
    path2.set(paths2)
    print(paths2)

# 设置frame容器
frame = tk.Frame(window, padx=3, pady=3)
frame.pack()
frame_left = tk.Frame(frame)
frame_right = tk.Frame(frame)
frame_left.pack(side='left')
frame_right.pack(side='right')

# 选择文件和选择文件夹的输入框
path = tk.StringVar()
path2 = tk.StringVar()
e1 = tk.Entry(frame_left, textvariable=path, width=50).pack(padx=5, pady=10)
e2 = tk.Entry(frame_left, textvariable=path2, width=50).pack(padx=5, pady=10)
# 三个数值的输入框
tPath1 = tk.StringVar()
tPath2 = tk.StringVar()
tPath3 = tk.StringVar()
t1 = tk.Entry(frame_left, textvariable=tPath1, width=50)
t2 = tk.Entry(frame_left, textvariable=tPath2, width=50)
t3 = tk.Entry(frame_left, textvariable=tPath3, width=50)
t1.pack(padx=5, pady=10)
t2.pack(padx=5, pady=10)
t3.pack(padx=5, pady=10)
# 按钮
tk.Button(frame_right, text='选择文件', font=fontStyle, width=18, height=1, command=lambda: askd()).pack(padx=3, pady=3)
tk.Button(frame_right, text='选择保存的文件夹', font=fontStyle, width=18, height=1, command=lambda: askd2()).pack(padx=3,pady=3)
tk.Button(frame_right, text='左边的数值', font=fontStyle, width=18, height=1, command=lambda: lbs1()).pack(padx=3, pady=3)
tk.Button(frame_right, text='顶部的数值', font=fontStyle, width=18, height=1, command=lambda: lbs2()).pack(padx=3, pady=3)
tk.Button(frame_right, text='比较的数据', font=fontStyle, width=18, height=1, command=lambda: lbs3()).pack(padx=3, pady=3)


frame2 = tk.Frame(window, padx=3, pady=3)
frame2.pack()
frame_left_01 = tk.Frame(frame2)
frame_right_01 = tk.Frame(frame2)
frame_left_01.pack(side='left')
frame_right_01.pack(side='right')
frame_left_02 = tk.Frame(frame_left_01)
frame_right_02 = tk.Frame(frame_left_01)
frame_left_02.pack(side='left')
frame_right_02.pack(side='right')
frame_left_03 = tk.Frame(frame_right_01)
frame_right_03 = tk.Frame(frame_right_01)
frame_left_03.pack(side='left')
frame_right_03.pack(side='right')

# 生成图表的单选按钮
var_1 = tk.StringVar()
var_1.set('A')
r1 = tk.Radiobutton(frame_left_02, text='不生成图表', font=fontStyleRadio, variable=var_1, value='A',).pack(padx=3, pady=3)
r2 = tk.Radiobutton(frame_right_02, text='生成折线图', font=fontStyleRadio, variable=var_1, value='B',).pack(padx=3, pady=3)

r3 = tk.Radiobutton(frame_left_03, text='生成柱状横图', font=fontStyleRadio, variable=var_1, value='C',).pack(padx=3, pady=3)
r4 = tk.Radiobutton(frame_right_03, text='生成柱状竖图', font=fontStyleRadio, variable=var_1, value='D',).pack(padx=3, pady=3)



frame = tk.Frame(window, padx=3, pady=3)
frame.pack()
frame_left2 = tk.Frame(frame)
frame_right2 = tk.Frame(frame)
frame_left2.pack(side='left')
frame_right2.pack(side='right')

tk.Button(frame_left2, text='清空', font=fontStyle, width=15, height=1, command=lambda: qk()).pack(padx=3, pady=3)
tk.Button(frame_right2, text='开始转换', font=fontStyle, width=15, height=1,
          command=lambda: ts(paths, paths2, t2.get(), t3.get(), var_1.get())).pack(padx=3, pady=3)

# 清空内容的方法
def qk():
    lb.destroy()
    path.set('')
    path2.set('')
    tPath1.set('')
    tPath2.set('')
    tPath3.set('')
    index__.clear()
    values2_.clear()
# 关键方法!!! 透视表生成的方法
def ts(path, paths2, columns_, values_, vars):
    # path 路径名  左边显示名称
    # 首先检测选择的文件是xls还是xlsx,如果说xls就用xlrd读取文件,不用额外填写。
    # 如果是xlsx,就要设置engine='openpyxl',使用openpyxl读取xlsx。 xlrd不能读取xlsx,openpyxl也不能读取xls文件。

    cc = path.endswith(".xls")
    if cc == True:
        df = pd.read_excel(paths)
    else:
        df = pd.read_excel(paths, engine='openpyxl')

    #                   index: 左边的数值  columns: 最上面的数值  values: 要比较的数值 aggfunc:有相同数据时相加 fill_value:空值设置为0  margins:求和
    c1 = df.pivot_table(index=index__, columns=[columns_], values=values2_, aggfunc=[np.sum], dropna=False, fill_value=0, margins=True)
    val_ = values_.replace('、', '')

    p11 = paths2 + val_ + '.xlsx'
    # 生成Excel文件
    c1.to_excel(p11)
    if vars != 'A':
        if vars == 'B':
            c1.plot(kind='line')
        if vars == 'C':
            c1.plot(kind='barh')
        if vars == 'D':
            c1.plot(kind='bar')
            # 生成图表
        plt.savefig(paths2 + val_ + '.png')
        plt.show()
    ts = tkinter.messagebox.showinfo(title='提示', message="转换成功!")
    if ts == 'ok':
        os.startfile(p11)
# 窗口循环显示
window.mainloop()

 如有不懂,可在下方提问。

 

 

标签:right,python,透视,frame,Excel,tk,import,left,pack
来源: https://blog.csdn.net/qq_41021581/article/details/120601227

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有