• 一个使用xlwings操作excel数据优化60倍处理效率的案例


    ☞ ░ 前往老猿Python博文目录

    一、引言

    老猿在将自己的博文数据(包括url地址、标题和阅读数量)从博客中获取后,使用xlwings保存到excel对象时发现,不同的处理方法性能相差非常大。

    案例程序每次获取博文数据后,对新的博文将其信息保存到excel,对老的博文则将其数据更新,每次处理的阅读量单列一列,存储数据类似如下:
    在这里插入图片描述
    前面两列分别为url和标题,后面随着处理次数增多会有多列数据记录下访问时间及当时的博文阅读数量,涉及处理的博文有900多篇,阅读量数据有近10列。

    二、案例背景说明

    本案例中只以输出阅读量数据为例,阅读量位于第三列开始,保存在二维列表urlReadInfoList中,二维列表中的元素也是列表,每个列表保存一行数据的多列阅读量。在初始输出时,老猿使用如下语句:

    def saveArticlesInfo():	
    	......
    	logPag("将文章阅读数量填入excel对象中...")
        line = 2  #第一行为标题,从第二行开始保存
        for readinfo in urlReadInfoList:
            sheet.range(line,3).value = readinfo #一次输出一行
            line += 1
        logPag("设置excel数据的宽度...")
    

    上面是拷贝了saveArticlesInfo的部分代码,其中使用的函数logPag是将对应参数信息前加一个输出时刻的具体时间值之后再输出,以跟踪代码耗时。

    针对这900多行10列的阅读量数据处理耗时近1分钟,具体输出信息如下:

    20200704 211802: 将文章阅读数量填入excel对象中...
    20200704 211858: 设置excel数据的宽度...
    

    三、优化措施

    为了提高效率,老猿将其采用以列为单位输出,为了保证前期代码不用修改,在此输出时做了个变换处理,将阅读量数据的行和列的维度交换了一下,下面是交换函数:

    def exchangeLineColumn(array):
        columncount = len(array[0])
        rowcount = len(array)
        columnData = []
        for i in range(columncount):
            columnData.append([])
    
        for line in array:
            columnPos = 0
            for column in line:
                columnData[columnPos].append(column)
                columnPos += 1
        return columnData
    
    

    然后在输出前调用该交换函数,将交换后的数据以列为单位输出。代码如下:

       logPag("将文章阅读数量填入excel对象中...")
       # line = 2
       # for readinfo in urlReadInfoList:
       #     sheet.range(line,3).value = readinfo
       #     line += 1
        readInfoList= exchangeLineColumn(urlReadInfoList)
        columnno = 3 #阅读量从第2行3列开始
        for readinfo in readInfoList:
             sheet.range(2,columnno).options(transpose=True).value = readinfo
             columnno += 1
        logPag("设置excel数据的宽度...")
    

    最后看运行结果:

    20200704 214611: 将文章阅读数量填入excel对象中...
    20200704 214611: 设置excel数据的宽度...
    

    以上输出结果可以看到,处理用时不到1秒,效率至少提高了60倍。

    补充说明:

    其实上面的方式还可以更好地解决办法,就是一次性写入多行多列:

       logPag("将文章阅读数量填入excel对象中...")
       sheet.range("C2").value = urlReadInfoList
       # line = 2
       # for readinfo in urlReadInfoList:
       #     sheet.range(line,3).value = readinfo
       #     line += 1
        #readInfoList= exchangeLineColumn(urlReadInfoList)
        #columnno = 3
        #for readinfo in readInfoList:
        #     sheet.range(2,columnno).options(transpose=True).value = readinfo
        #     columnno += 1
       logPag("设置excel数据的宽度...")
    

    四、结论

    使用xlwings操作excel时,对行和列的访问尽量避免单个单元数据访问,使用整行或整列数据操作时,最好是一次性尽可能操作多的数据,如果行列数据分布极度不均时这可以大幅提高效率。

    具体操作方法请参考《Python学习随笔:使用xlwings设置和操作excel多行多列数据以及设置数据字体颜色填充色对齐方式的方法》。

    跟老猿学Python、学5G!

    ☞ ░ 前往老猿Python博文目录

  • 相关阅读:
    Leetcode--First Missing Positive
    Leetcode--LRU Cache
    java--遍历自定义数组
    爬网页?--Chrome帮你计算XPath
    log4j2配置
    winedt设置自动显示行号[latex]
    墓地雕塑-LA3708
    ctex moderncv版本更新--用latex写一个漂亮的简历
    用Jekyll在github上写博客——《搭建一个免费的,无限流量的Blog》的注脚
    用gameMaker做个小游戏
  • 原文地址:https://www.cnblogs.com/LaoYuanPython/p/13643460.html
Copyright © 2020-2023  润新知