【Python自動化Excel】pandas處理Excel的“分分合合”

位元組雜談發表於2022-02-22

話說Excel資料表,分久必合、合久必分。Excel資料表的“分”與“合”是日常辦公中常見的操作。手動操作並不困難,但資料量大了之後,重複性操作往往會令人崩潰。利用Python的Pandas庫,便可以自動實現Excel資料表的“分分合合”。下面結合例項來分享本人整理的實用程式碼片段。(如有更好的方式,歡迎批評指正)

主目錄
主目錄

分:縱向“分”

從資料平臺(如問卷平臺)中匯出的資料往往是清單型的,每一行都是一條記錄,資料量大的時候,表格往往是很“長”的。有時需要按照某列的不同數值,將一個總表“分”成單獨的一些Excel檔案。

縱向“分”原理圖
縱向“分”原理圖

一個工作表“分”為多個Excel檔案

def to_excelByColName(sourceDf,colName,outPath,excelName):
    '''
        縱向“分”:一個工作表“分”為多個Excel檔案
        根據指定的列名中的不同值,分解Excel,並儲存成多個Excel檔案。
        sourceDf:原始的DataFrame
        colName:指定列名
        outPath:輸出路徑
        excelName:檔名,加.xlsx字尾
    '''
    colNameList = sourceDf[colName].drop_duplicates().tolist()
    for eachColName in colNameList:
        sourceDf[sourceDf[colName]==eachColName].to_excel('/'.join([outPath,eachColName+excelName]),index=False)

例如:將20個班級1000名學生的總表,按班級分成20個Excel檔案。

呼叫to_excelByColName函式,效果如下:

to_excelByColName(sourceDf = sourceDf,colName="班級",outPath=".\分班資料表",excelName="生成資料表.xlsx")
縱向分,演示效果
縱向分,演示效果

一個工作表“分”為一個檔案的多個sheet

def to_excelByColNameWithSheets(sourceDf,colName,outPath):
    '''
        縱向“分”:一個工作表“分”為一個檔案的多個sheet
        根據指定的列名中的不同值,分解Excel,並儲存成單個Excel檔案的多個Sheet。
        sourceDf:原始的DataFrame
        colName:指定列名
        outPath:輸出路徑,加.xlsx字尾
    '''
    writer = pd.ExcelWriter(outPath)
    colNameList = sourceDf[colName].drop_duplicates().tolist()
    for eachColName in colNameList:
        sourceDf[sourceDf[colName]==eachColName].to_excel(writer,sheet_name=eachColName)
    writer.save()

例如:將20個班級1000名學生的總表,按班級分成1個Excel檔案的20個sheet表。

呼叫to_excelByColNameWithSheets函式,效果如下:

to_excelByColNameWithSheets(sourceDf = sourceDf,colName="班級",outPath=".\分班資料表\生成資料表.xlsx")
生成效果圖
生成效果圖

分:橫向“分”

在處理資料的時候,有時需要新增多個輔助列,這樣也會讓資料表越來越“寬”。而最終我們只需要某些關鍵列即可,那麼這就涉及到橫向資料分割,或者說提取某些列保持成一個單獨的資料表。橫向的分割只需要給DataFrame傳入列名列表即可。

例如:只需要資料表中的姓名和班級欄位,可以這樣寫。

df1 = sourceDf[["姓名","班級"]]
df1.to_excel("只含有姓名和班級的資料表.xlsx")

合:縱向“合”

對於結構相同的資料,在資料處理時可以將其在縱向上拼接,方便一起處理。

縱向“合”原理圖
縱向“合”原理圖

多個Excel檔案合併成一個工作表

def readExcelFilesByNames(fpath,fileNameList=[],header=0):
    '''
        縱向“合”:多個Excel檔案合併成一個工作表
        讀取路徑下指定的Excel檔案,併合併成一個總的DataFrame。
        每個Excel檔案的資料表格式上要一致。
        1.fpath:必填,是Excel檔案所在路徑,不加檔名
        2.fileNameList:需要讀取的Excel檔名列表
        3.header:指定讀取的行數
    '''
    outdf = pd.DataFrame()
    for fileName in fileNameList:
        tempdf =pd.read_excel('/'.join([fpath,fileName]),header = header)
        outdf = pd.concat([outdf,tempdf])
    return outdf

例如:將20個班級的Excel檔案,合併成一個資料表

呼叫readExcelFilesByNames函式,效果如下:

fileNameList = [
    "六1班資料表.xlsx",    "六2班資料表.xlsx",    "六3班資料表.xlsx",    "六4班資料表.xlsx",
    "六5班資料表.xlsx",    "六6班資料表.xlsx",    "六7班資料表.xlsx",    "六8班資料表.xlsx",
    "六9班資料表.xlsx",    "六10班資料表.xlsx",    "六11班資料表.xlsx",    "六12班資料表.xlsx",
    "六13班資料表.xlsx",    "六14班資料表.xlsx",    "六15班資料表.xlsx",    "六16班資料表.xlsx",
    "六17班資料表.xlsx",    "六18班資料表.xlsx",    "六19班資料表.xlsx",    "六20班資料表.xlsx",
]
readExcelFilesByNames(fpath = ".\分班資料表",fileNameList=fileNameList)
合併資料表,演示效果
合併資料表,演示效果

多個Sheet合併成一個工作表

def readExcelBySheetsNames(fpath,header = 0,prefixStr = "",sheetNameStr ="sheetName",prefixNumStr = "prefixNum"):
    '''
        縱向“合”:多個Sheet合併成一個工作表
        讀取所有的Excel檔案的sheet,併合並返回一個總的DataFrame。
        每個sheet的資料表格式上要一致。
        1.fpath:必填,是Excel檔案的路徑,加檔名
        2.會生成兩個新列:sheetName和prefixNum,方便資料處理
            sheetName列是所有sheet的名稱列
            prefixNum列是計數列
        3.header:指定讀取的行數
    '''
    xl = pd.ExcelFile(fpath)
    # 獲取Excel檔案內的所有的sheet名稱
    sheetNameList = xl.sheet_names
    outfd = pd.DataFrame()
    num  = 0 
    for sheetName in sheetNameList:
        num += 1
        data = xl.parse(sheetName,header=header)
        # 產生sheet名稱列和計數列
        data[sheetNameStr] = sheetName
        data[prefixNumStr] = prefixStr +str(num)
        # 資料表拼接
        outfd = pd.concat([outfd,data.dropna()])
    xl.close()
    return outfd

如下呼叫readExcelBySheetsNames,執行效果如下:

readExcelBySheetsNames(fpath = ".\分班資料表\總資料表.xlsx",sheetNameStr ="sheet名",prefixNumStr = "sheet序號")
演示效果
演示效果

合:橫向“合”

對於不同Excel工作表之間的橫向合併,主要是用根據某些列(如:姓名、身份證號等)進行合併。在pandas庫中可以用merge方法來實現,這是個十分好用的方式,展開講篇幅較長,後續詳細整理。

DataFrame.merge(right, how='inner', on=None, left_on=None, right_on=None, left_index=False, right_index=False, sort=False, suffixes=('_x', '_y'), copy=True, indicator=False, validate=None)

結語

本文所談的Python處理Excel檔案方式主要是基於pandas庫的,主要針對的是清單型的資料表。清單型的資料表在下面的文章中有詳細介紹:

https://www.cnblogs.com/wansq/p/15869594.html

資料表的主要涉及的是檔案儲存(寫入),對程式來說屬於輸出環節;

資料表的主要針對的是檔案開啟(讀取),對程式而言屬於輸入環節。

以上程式碼在針對大量重複性的表格分與合時,優勢巨大;但對於偶爾、少量的分與合,也許用滑鼠點選更快。

技術沒有好壞之分,需要我們靈活使用!

關注公眾號“位元組雜談”,

回覆“分分合合”即可下載本文的程式碼,

開箱即用!

 

相關文章