作者|珍惜
来源 | Jake 的 IT 之旅
决定写这篇文章的初衷是从一个男人的伙伴的问题开始,关于“如何根据数据源用Python手动生成数据透视表”,这个问题背后有一个特别好的解决方案网站直接生成小程序,让代码为我们做重复工作,从而减少工作量并减少错误。
Python开发的小工具,其实就是一个Python程序打包成exe,分享后即可使用。即使 notebook 没有安装 Python 环境,也可以使用。使用代码来提高工作效率并最大限度地减少加班。
内容大纲
需求背景
工作中的重复操作将在供应商名称、月份和存储量三个数组的帮助下重生为所需的数据透视表格式。
安装第三方依赖
创建桌面窗口,这里使用tkinter,它是Python自带的GUI库,安装后即可使用。
pip install tkinter
使用pyinsatller将程序打包成exe,用处是不需要将代码部署到服务器,直接将打包好的exe发给对方,直接使用即可。对这些小巧轻便的功能非常友好。
pip install pyinstaller
代码
生成数据透视表和过滤数据的Excel文件,文件名:excel_to_pivot.py
import pandas as pd
import numpy as np
class ExcelToPivot(object):
def __init__(self, filename, file_path):
self.file_name = filename
self.file_path = file_path
"""
excel自动转透视表功能
返回透视结果
"""
def excel_Pivot(self):
print(self.file_path)
data = pd.read_excel(self.file_path)
data_pivot_table = pd.pivot_table(data, index=['供应商名称', '月份'], values=["入库金额"], aggfunc=np.sum)
return data_pivot_table
"""
按条件筛选,并保存
"""
def select_data(self, name, month):
data_pivot_table = self.excel_Pivot()
data_new = data_pivot_table.query('供应商名称 == ["{}"] & 月份 == {}'.format(name, month))
data_new.to_excel('{}.xlsx'.format(str(self.file_name).split('.')[0]))
return '筛选完成!'
if __name__ == '__main__':
filename = input("请输入文件名字:")
path = 'C:/Users/cherich/Desktop/' + filename
pross = ExcelToPivot(filename, path)
print(pross.select_data("C", 4))
设计桌面窗口函数,文件名:opration.py
from tkinter import Tk, Entry, Button, mainloop
import tkinter.filedialog
import excel_to_pivot
from tkinter import messagebox
from tkinter import ttk
def Upload():
global filename, data_pivot_table
try:
filename = tkinter.filedialog.askopenfilename(title='选择文件')
pross = excel_to_pivot.ExcelToPivot(str(filename).split('/')[-1], filename)
data_pivot_table = pross.excel_Pivot()
messagebox.showinfo('Info', '转换成功!')
except Exception as e:
print(e)
messagebox.showinfo('Info', '转换失败!')
def select(name, month):
try:
print('供应商名称 == ["{}"] & 月份 == {}'.format(name, month))
data_new = data_pivot_table.query('供应商名称 == ["{}"] & 月份 == {}'.format(name, month))
data_new.to_excel('{}.xlsx'.format(str(filename).split('.')[0]))
messagebox.showinfo('Info', '筛选完成并生成文件!')
root.destroy()
except Exception as e:
print(e)
messagebox.showinfo('Info', '筛选失败!')
root = Tk()
root.config(background="#6fb765")
root.title('自动转透视表小工具')
root.geometry('500x250')
e1 = Entry(root, width=30)
e1.grid(row=2, column=0)
btn1 = Button(root, text=' 上传文件 ', command=Upload).grid(row=2, column=10, pady=5)
box1 = ttk.Combobox(root)
# 使用 grid() 来控制控件的位置
box1.grid(row=5, sticky="NW")
# 设置下拉菜单中的值
box1['value'] = ('A', 'B', 'C', 'D', '供应商')
# 通过 current() 设置下拉菜单选项的默认值
box1.current(4)
box2 = ttk.Combobox(root)
box2.grid(row=5, column=1, sticky="NW")
box2['value'] = (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, '月份')
box2.current(12)
# 编写回调函数,绑定执行事件
def func(event):
global b1, b2
b1 = box1.get()
b2 = box2.get()
# 绑定下拉菜单事件
box1.bind("<>", func)
box2.bind("<>", func)
btn2 = Button(root, text=' 筛选数据 ', command=lambda: select(b1, b2)).grid(row=30, column=10, pady=5)
mainloop()
如果运行结果如上,说明代码没有问题,可以进行下一步。
打包Python程序生成exe
打开一个DOS窗口,切换到两个py文件所在的目录。注意不要在路径中使用英语。
pyinsatller -F -w opration.py
pyinstaller 指令的常见可选参数:
在当前目录下会生成两个文件夹:build 和 dist。以上dist都是可执行的exe文件网站直接生成小程序,将快捷方式发送到桌面,点击opration.exe运行,可以将其快捷方式发送到桌面,双击即可。
解决exe文件可能过大的问题
有的小伙伴前不久刚刚安装了Python环境,所以可能不存在这个文件太大的问题。例如,我在笔记本中安装了很多 Python 依赖包和 anaconda。打包的文件是660M,打包时间长,执行还是卡住。后来经过整改,缩小到31M,打包速度快,秒执行。解决方法是在Windows系统下安装Python虚拟环境,前提是笔记本上已经安装了Python,然后才能进行以下操作。
找到 Python 所在的路径。如果忘记了,可以在笔记本左下角搜索【编辑系统环境变量】-【用户变量】-【PATH】。
配置虚拟环境
虚拟环境可以理解为 Python 类库的一个副本,可以在其中安装私有包而不影响系统上安装的全局 Python 类库。虚拟环境有助于防止系统 Python 库中的包混淆和版本冲突。
重要的是不同的虚拟环境可以构建不同的 Python 版本。创建的时候,我们需要一个比较“干净”的Python环境,不需要安装太多的依赖包,防止exe包文件过大,所以使用了虚拟环境。
安装虚拟环境依赖
pip install virtualenv
pip install virtualenvwrapper-win
创建虚拟环境命令
mkvirtualenv -p="C:UserscherichAppDataLocalProgramsPythonPython38python.exe" py38
步入虚拟环境,可以看到只有几个默认的Python库
这时候可以测试一下代码,看看是否缺少相关的依赖。比如我缺Pandas,openpyxl,你可以根据pipinstall包名安装。最重要的一点:必须重新安装pyinstaller才能减少文件。
以上操作完成后就可以进行打包了,最后一步之后就可以退出虚拟环境了。
退出虚拟环境
deactivate
整个手工思路的实现就完成了。您可以将整个过程应用于现有的重复性工作。过程中有两点需要注意,如下:
尽量不要使用英文路径,否则会报一些莫名其妙的错误。
导出包是为了尽量避免使用import*导出不必要的包,节省打包和执行时间。
让代码手动工作,节省时间,摸鱼,玩小游戏~
- - - - 结尾 - - - - - -
特色内容