在公司某个平台升级后,导出数据再也不能用 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_duplicatessort_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 的去重版表格全部导入到列表中,再去重,最后生成最终版文件就完事了。当然我觉得不需要先去重再导,直接所有内容导入到列表再统一去重就完事了,不过之前试过了,内存快炸了,以后有空再研究吧。