在公司某个平台升级后,导出数据再也不能用 navicat 导出了,毕竟厂商都换成 Elasticsearch 数据库,我懂个屁,那就只能老实用平台自带的导出功能实现每周导出需求。可是啊,他们设定的导出只能单文件导出60000行,导致50W的内容都要拆分几十个文件。
在初期我是用 WPS 批量合并表格,再删除重复项,再继续合并(Excel 有最大行数限制),光是把所有节点的内容导出了都要用40分钟,实在是太没效率了。没有办法,只有自动化才能解放效率,然后我就开始抄网上的代码实现关于 python 表格的内容了。
代码
(20210614:这代码其实就是有多少个进程就创造多少个进程,正常来说最好用 queue 限制数目)
这是整合在一起的乐色代码,写得很烂
import pandas as pd
import os
import threading
import multiprocessing as mp
import shutil
# 提前定义目录名称和文件格式
rootpath = os.getcwd()
excel_dir = rootpath +'\\excel'
name = "相关内容"
outputpath = rootpath + '\\result'
def quchong(a):
# 读取 excel_dir 的上所有文件
frame = pd.read_excel(excel_dir + "\\" + a)
# 用frame的数据创建dataframe
data = pd.DataFrame(frame)
# 去重
data.drop_duplicates(['去重列名称'], keep='first', inplace=True)
# 输出到result目录,不要索引号
data.to_excel(outputpath + "\\" + "out-" + a +'.xlsx', index=False)
def hebing():
# 读取result的所有文件
dirlist = []
for dirpath,dirname,filename in os.walk(outputpath):
for i in filename:
dirlist.append(os.path.join(dirpath,i))
# 将所有文件交给pandas读取
dflist = []
for i in dirlist:
dflist.append(pd.read_excel(i))
# 全合并
all = pd.concat(dflist)
# 继续去重
all.drop_duplicates(['去重列名称'], keep='first', inplace=True)
# 需求要降序
all.sort_values(by='降序列名称', ascending = False)
# 输出
all.to_excel('final.xlsx', index=False)
print('complate')
def clean():
# 清空目录文件
shutil.rmtree('excel')
shutil.rmtree('result')
os.mkdir('excel')
os.mkdir('result')
def main():
# 多进程,具体原理我不懂,是照抄网络的
threads = []
x=1
for i in range(len(os.listdir(excel_dir))):
named = name + str(x) +".xls"
t= mp.Process(target=quchong,args=(named,))
threads.append(t)
x+=1
for t in threads:
t.start()
for t in threads:
t.join()
hebing()
clean()
if __name__ == '__main__':
main()
分析
为什么要用多进程
如果用循环会一个一个来,效率很低,CPU 的利用率才10%。使用多进程可以创造多个进程处理多个表格,比一个一个处理快个几分钟。当然我这个代码是比较暴力,直接开几十个进程一起处理,CPU 会短暂炸裂。
多线程我试过,但那是对数据操作有用,对文件操作的话没有多大帮助。
pandas
Pandas是 Python 第三方库,提供高性能易用数据类型和分析工具1,在本次需求可以实现对表格数据的分析与整合。
在本文我主要用三个函数:drop_duplicates
、sort_values
drop_duplicates
data.drop_duplicates(['a'],keep='first', inplace=True)
data 根据 'a' 组合列删除重复项,默认保留第一个出现的值组合。传入参数keep='last'则保留最后一个2,当 inplace = True传递时,数据将被重命名(它不返回任何内容) 3
sort_values
data.sort_values(by='a', ascending = False)
根据 'a' 列名称进行降序操作,ascending = True 时,将会升序
总结
Python3 还没完全啃完,我还是个脚本小子而已。
其实脚本的大概原理就是,我先将每个文件都去重,再导出对应文件的去重版。紧接着对导出在 result 的去重版表格全部导入到列表中,再去重,最后生成最终版文件就完事了。当然我觉得不需要先去重再导,直接所有内容导入到列表再统一去重就完事了,不过之前试过了,内存快炸了,以后有空再研究吧。
发表评论