一個使用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博文目錄


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM