一个使用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、学5G!

☞ ░ 前往老猿Python博文目录

猜你喜欢

转载自blog.csdn.net/LaoYuanPython/article/details/107132602