[Python] 用Python處理Excel(一)

用Python 進行Excel 文件的整理大致分爲這幾個流程: 讀取-整理-寫入

有時寫入的時候需要按照規定的格式填入指定的位置,這時可以選擇整理的時候就按照指定的位置進行整理,方便寫入。

首先是模塊選擇,這裏我選擇了openpyxl , Pandas 模塊。Openpyxl用於操作Excel寫入可以說是相當方便,而Pandas用於整理數據

也是不錯的選擇。

對於數據源並不是很規範的時候,整理的過程耗時比較長。

下面開始我們的示例,這是我們單位工作時用到的表,表數據其實是非常不規範的。

以下兩張表可以視爲兩個報告表,並不是很好的數據源。所以整理數據源就是第一大塊工作了。

這是src表,包括了pn列和日期列

這是tg表,有pn列 model列,部分日期列

========================這是分割線================================

1. 文件讀取 :

Openpyxl : wb = load_workbook(‘url’)   除了url以外還有幾個參數可供選擇 : read_only[大文件時啓用] ; data_only[公式or 值]

Wb.sheetnames – 獲取sheet名

Wb[‘sheetname’] – 獲取 sheet

sheet[‘A1’].value || sheet.cell(row=1,column=1).value – 獲取指定單元格值

sheet.max_row , sheet.max_column - 獲取行列數

sheet[‘A1’: ‘C3’] – 獲取指定區域

Pandas : src = pd.read_excel(‘url’,sheet_name=’’,header=0)  以外還有幾個參數: sheet_name[可以寫序號,可以選多張] ; index_col[設置爲索引列] (此方法讀取出的數據爲DataFrame格式)

Src[‘column’] – 讀取指定列數據

import pandas as pd

from openpyxl import load_workbook

# 讀取文件

src = pd.DataFrame(pd.read_excel('/Users/Documents/Code/Python/excel/dataSource.xlsx',sheet_name=0,header=2))

tg = pd.DataFrame(pd.read_excel('/Users/Documents/Code/Python/excel/report.xlsx',sheet_name=0,header=3))

tg_wb = load_workbook('/Users/Documents/Code/Python/excel/report.xlsx',data_only=True)

src_wb = load_workbook('/Users/Documents/Code/Python/excel/dataSource.xlsx',data_only=True)

tg_sheet = tg_wb['Sheet1']

src_sheet = src_wb['Sheet1']

=========================這是分割線==========================

2. 數據整理

定義索引:使用Pandas讀取的數據可以定義序列 src.set_index(‘index’)

# 設置索引

df_src = src.set_index('pn')

對於序列不規範情況,找出其規律比如分組

# src_pn集合
src_pnList = []
for pn in src['pn']:
    src_pnList.append(pn)

篩選: 確定一個基準列後,就可以進行篩選。篩選一般用loc , iloc 比較多 loc[1,’column’] , 對於序列化的DataFrame 可直接用loc[‘row’,’column’] ; iloc一般爲iloc[1,1]

遍歷:整理時一般使用 tg = update(src) 比較方便,但前提是序列一致。不一致時我們需要自己重寫。

特殊情況處理:待寫入數據爲nan時,無法寫入新數據,需要先判斷用pd.isna(),然後可以賦值爲0

for i in range(0,tg.shape[0]):
    # 如果model 是 1
    if tg.loc[i,'model'] == 1:
        # 如果有一個元素
        if len(tg.loc[i,'pn']) == 1:
            for j in range(3,tg.shape[1]+1):
                # 寫入
                tg.loc[i,tg.columns[j-1]] = df_src.loc[tg.loc[i,'pn'],tg.columns[j-1]]
        # 如果有多個元素
        else:
            # 拆分成數組
            pn_list = (tg.loc[i,'pn']).split('/')
            # 遍歷元素組
            for n in pn_list:
                # 如果在數據源內存在
                if n in src_pnList:    
                    # 遍歷目標                
                    for k in range(3,tg.shape[1]+1):
                        # 如果目標單元格是空
                        if pd.isna(tg.loc[i,tg.columns[k-1]]):
                            tg.loc[i,tg.columns[k-1]] = 0
                        # 累積數字
                        tg.loc[i,tg.columns[k-1]] += df_src.loc[n,tg.columns[k-1]]

至此 數據的整理就差不多了

別忘記給整理的數據添加一個索引,並且確定唯一值

# 添加整理好的索引 - 確認待寫入的唯一值
df_tg = tg[tg['model'] == 1].set_index('pn')

=====================我是分割線==========================

直接寫入:由於數據整理時依照待寫入數據的格式整理,故寫入過程比較簡單。可直接使用cell(row=1,column=1).value進行

最後別忘記wb.save(‘url’)

# df_tg pn 集合
df_tg_pnList = []
for df_tg_pn in df_tg.index:
    df_tg_pnList.append(df_tg_pn)

# 遍歷循環寫入
for i in range(5, tg_sheet.max_row + 1):
    # 獲取目標源的pn
    tg_pn = tg_sheet.cell(row=i,column=1).value
    # 如果目標源pn在DataFrame內,並且model==1
    if (tg_pn in df_tg_pnList) & (tg_sheet.cell(row=i,column=2).value == 1):
        # 遍歷日期相關所有列
        for j in range(3, tg_sheet.max_column + 1):
            # 賦值
            tg_sheet.cell(row=i,column=j).value = df_tg.loc[tg_pn,df_tg.columns[j-2]]
# 寫入excel
tg_wb.save('/Users/zean/Documents/Code/Python/excel/reportNew.xlsx')

=========================大功告成==========================

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章