久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx

Python怎么處理Excel文件

本篇內容介紹了“Python怎么處理Excel文件”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

為杜集等地區用戶提供了全套網頁設計制作服務,及杜集網站建設行業解決方案。主營業務為成都網站設計、做網站、杜集網站設計,以傳統方式定制建設網站,并提供域名空間備案等一條龍服務,秉承以專業、用心的態度為用戶提供真誠的服務。我們深信只要達到每一位用戶的要求,就會得到認可,從而選擇與我們長期合作。這樣,我們也可以走得更遠!

「問題說明」

這次要處理的excel有兩個sheet,要根據其中一個sheet的數據來計算另外一個sheet的值。造成問題的點在于,要計算值的sheet里不僅僅有數值,還有公式。我們來看一下:

Python怎么處理Excel文件

如上圖所示,這個excel一共有兩個sheet:CP和DS,我們要按照一定的業務規則,根據CP中的數據計算DS對應單元格的數據。圖中藍色方框框出來的是帶公式的,而其他區域是數值。

我們來看看,如果我們按照之前說的處理邏輯,把excel一次性批量讀取到dataframe處理,然后再一次性批量寫回去有啥問題。這部分代碼如下:

import pandas as pd
import xlwings as xw
 
#要處理的文件路徑
fpath = "data/DS_format.xlsm"
 
#把CP和DS兩個sheet的數據分別讀入pandas的dataframe
cp_df = pd.read_excel(fpath,sheet_name="CP",header=[0])
ds_df = pd.read_excel(fpath,sheet_name="DS",header=[0,1])
 
#計算過程省略......
 
#保存結果到excel       
app = xw.App(visible=False,add_book=False)
ds_format_workbook = app.books.open(fpath)
ds_worksheet = ds_format_workbook.sheets["DS"]
ds_worksheet.range("A1").expand().options(index=False).value = ds_df 
ds_format_workbook.save()
ds_format_workbook.close()
app.quit()

如上代碼存在的問題在于,pd.read_excel()方法從excel里讀取數據到dataframe的時候,對于有公式的單元格,會直接讀取公式計算的結果(如果沒有結果則返回Nan),而我們寫入excel的時候是直接把dataframe一次性批量寫回的,這樣之前帶公式的單元格,被寫回的就是計算出來的值或Nan,而丟掉了公式。

好了,問題出現了,我們該如何解決呢?這里會想到兩個思路:

  • dataframe寫回excel的時候,不要一次性批量寫回,而是通過行和列的迭代,只寫回計算的數據,有公式的單元格不動;

  • 讀取excel的時候,有沒有辦法做到對于有公式的單元格,讀取公式,而不是讀取公式計算的結果;

我確實按照上面兩個思路分別嘗試了一下,我們一起來看一下。

「方案1」

如下代碼嘗試遍歷dataframe然后按單元格寫入對應的值,有公式的單元格不動

#根據ds_df來寫excel,只寫該寫的單元格
for row_idx,row in ds_df.iterrows():
    total_capabity_val = row[('Total','Capabity')].strip()
    total_capabity1_val = row[('Total','Capabity.1')].strip()
    #Total和1Gb  Eqv.所在的行不寫
    if total_capabity_val!= 'Total' and total_capabity_val != '1Gb  Eqv.':
        #給Delta和LOI賦值
        if total_capabity1_val == 'LOI' or total_capabity1_val == 'Delta':
            ds_worksheet.range((row_idx + 3 ,3)).value = row[('Current week','BOH')]
            print(f"ds_sheet的第{row_idx + 3}行第3列被設置為{row[('Current week','BOH')]}") 
        #給Demand和Supply賦值
        if total_capabity1_val == 'Demand' or total_capabity1_val == 'Supply':
            cp_datetime_columns = cp_df.columns[53:]
            for col_idx in range(4,len(ds_df.columns)):
                ds_datetime = ds_df.columns.get_level_values(1)[col_idx]
                ds_month = ds_df.columns.get_level_values(0)[col_idx]
                if type(ds_datetime) == str and ds_datetime != 'TTL' and ds_datetime != 'Total' and (ds_datetime in cp_datetime_columns):
                    ds_worksheet.range((row_idx + 3,col_idx + 1)).value = row[(f'{ds_month}',f'{ds_datetime}')]
                    print(f"ds_sheet的第{row_idx + 3}行第{col_idx + 1}列被設置為{row[(f'{ds_month}',f'{ds_datetime}')]}") 
                elif type(ds_datetime) == datetime.datetime and (ds_datetime in cp_datetime_columns):
                    ds_worksheet.range((row_idx + 3,col_idx + 1)).value = row[(f'{ds_month}',ds_datetime)]     
                    print(f"ds_sheet的第{row_idx + 3}行第{col_idx + 1}列被設置為{row[(f'{ds_month}',ds_datetime)]}")

如上的代碼確實解決了問題,也即有公式的單元格的公式被保留了。但是,根據我們文章開頭提到的Python處理excel的忠告,這個代碼是有嚴重性能問題的,因為它通過api頻繁操作excel的單元格,導致寫入非常慢,在我的老邁Mac本上一共跑了40分鐘,簡直不可接受,故該方案只能放棄。

「方案2」

這個方案是希望做到讀取excel有公式值的單元格的時候,能保留公式值。這只能從各個Python的excel庫的API來尋找有無對應的方法了。Pandas的read_excel()方法我仔細看了一下沒有對應的參數可以支持。Openpyxl我倒是找到了一個API可以支持,如下:

import openpyxl
ds_format_workbook = openpyxl.load_workbook(fpath,data_only=False)
ds_wooksheet = ds_format_workbook['DS']
ds_df =  pd.DataFrame(ds_wooksheet.values)

關鍵是這里的data_only參數,為True則返回數據,為False的情況下可以保留公式值

本以為找到了對應解決方案正一頓竊喜,但當我看到通過openpyxl讀取到dataframe中的數據結構的時候,才被破了一盆冷水。因為我的excel表的表頭是比較復雜的兩級的表頭,表頭中還存在合并和拆分單元格的情況,這樣的表頭被openpyxl讀取到dataframe后,沒有按照pandas的多級索引進行處理,而是簡單的被處理成數字索引0123...

但我對dataframe的計算會依賴多級索引,因此openpyxl的這種處理方式導致我后面的計算無法處理。

openpyxl不行,再看看xlwings呢?通過對xlwings API文檔的一通尋找,還真給我找到了,如下所示:

Python怎么處理Excel文件

Range類提供了一個Property叫formula,可以獲取和設置formula。

看到這個我簡直如獲至寶,趕緊代碼操練起來。也許出于慣性,又或許是被之前按行列單元格操作excel的效率搞怕了,我直接先想到的方案還是一次性批量搞定,也即一次性讀取excel所有的公式,然后再一次性寫回去,所以我一開始的代碼是這樣的:

#使用xlwings來讀取formula
app = xw.App(visible=False,add_book=False)
ds_format_workbook = app.books.open(fpath)
ds_worksheet = ds_format_workbook.sheets["DS"]
#先把所有公式一次性讀取并保存下來
formulas = ds_worksheet.used_range.formula
 
#中間計算過程省略...
 
#一次性把所有公式寫回去
ds_worksheet.used_range.formula = formulas

可是我想錯了,ds_worksheet.used_range.formula讓我誤解只會返回excel中的有公式的單元格的公式,但其實它返回的是所有的單元格,只是對有公式的單元格保留了公式。所以,當我重新寫回公式的時候,會覆蓋掉我通過dataframe計算完并寫入excel的其他的值。

既然這樣的話,那我只能對有公式的單元格分別處理而不是一次性處理了,所以代碼得這樣寫:

#使用xlwings來讀取formula
app = xw.App(visible=False,add_book=False)
ds_format_workbook = app.books.open(fpath)
ds_worksheet = ds_format_workbook.sheets["DS"]
 
#保留excel中的formula
#找到DS中Total所在的行,Total之后的行都是formula
row = ds_df.loc[ds_df[('Total','Capabity')]=='Total ']
total_row_index = row.index.values[0]
#獲取對應excel的行號(dataframe把兩層表頭當做索引,從數據行開始計數,而且從0開始計數。excel從表頭就開始計數,而且從1開始計數)
excel_total_row_idx = int(total_row_index+2)
#獲取excel最后一行的索引
excel_last_row_idx = ds_worksheet.used_range.rows.count
#保留按日期計算的各列的formula
I_col_formula = ds_worksheet.range(f'I3:I{excel_total_row_idx}').formula
N_col_formula = ds_worksheet.range(f'N3:N{excel_total_row_idx}').formula
T_col_formula = ds_worksheet.range(f'T3:T{excel_total_row_idx}').formula
U_col_formula = ds_worksheet.range(f'U3:U{excel_total_row_idx}').formula
Z_col_formula = ds_worksheet.range(f'Z3:Z{excel_total_row_idx}').formula
AE_col_formula = ds_worksheet.range(f'AE3:AE{excel_total_row_idx}').formula
AK_col_formula = ds_worksheet.range(f'AK3:AK{excel_total_row_idx}').formula
AL_col_formula = ds_worksheet.range(f'AL3:AL{excel_total_row_idx}').formula
#保留Total行開始一直到末尾所有行的formula
total_to_last_formula = ds_worksheet.range(f'A{excel_total_row_idx+1}:AL{excel_last_row_idx}').formula
 
#中間計算過程省略...
 
#保存結果到excel                 
#直接把ds_df完整賦值給excel,會導致excel原有的公式被值覆蓋
ds_worksheet.range("A1").expand().options(index=False).value = ds_df 
#用之前保留的formulas,重置公式
ds_worksheet.range(f'I3:I{excel_total_row_idx}').formula = I_col_formula
ds_worksheet.range(f'N3:N{excel_total_row_idx}').formula = N_col_formula
ds_worksheet.range(f'T3:T{excel_total_row_idx}').formula = T_col_formula
ds_worksheet.range(f'U3:U{excel_total_row_idx}').formula = U_col_formula
ds_worksheet.range(f'Z3:Z{excel_total_row_idx}').formula = Z_col_formula
ds_worksheet.range(f'AE3:AE{excel_total_row_idx}').formula = AE_col_formula
ds_worksheet.range(f'AK3:AK{excel_total_row_idx}').formula = AK_col_formula
ds_worksheet.range(f'AL3:AL{excel_total_row_idx}').formula = AL_col_formula
ds_worksheet.range(f'A{excel_total_row_idx+1}:AL{excel_last_row_idx}').formula = total_to_last_formula
 
ds_format_workbook.save()
ds_format_workbook.close()
app.quit()

經測試,如上代碼完美地解決我的需求,而且性能上也完全沒問題。

“Python怎么處理Excel文件”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注創新互聯網站,小編將為大家輸出更多高質量的實用文章!

文章名稱:Python怎么處理Excel文件
本文網址:http://www.js-pz168.com/article38/pojopp.html

成都網站建設公司_創新互聯,為您提供電子商務ChatGPT域名注冊響應式網站軟件開發小程序開發

廣告

聲明:本網站發布的內容(圖片、視頻和文字)以用戶投稿、用戶轉載內容為主,如果涉及侵權請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網站立場,如需處理請聯系客服。電話:028-86922220;郵箱:631063699@qq.com。內容未經允許不得轉載,或轉載時需注明來源: 創新互聯

成都網站建設公司
久久99久久人婷婷精品综合_超碰aⅴ人人做人人爽欧美_亚洲电影第三页_日韩欧美一中文字暮专区_波多野结衣的一区二区三区_婷婷在线播放_人人视频精品_国产精品日韩精品欧美精品_亚洲免费黄色_欧美性猛交xxxxxxxx
国产成人亚洲精品青草天美| 久久99精品久久久久久三级| 久久精品国产美女| 色噜噜夜夜夜综合网| 日韩精品一区二区三区在线播放| 亚洲伦理在线精品| 国精产品一区一区三区mba视频| 91久久大香伊蕉在人线| 亚洲国产欧美一区二区三区不卡| 日韩欧美不卡在线观看视频| 亚洲特黄一级片| 国内外精品视频| 国语精品中文字幕| 欧美日韩精品三区| 18成人在线观看| 国产一区二区毛片| 欧美日韩在线精品| 日韩欧美一区二区久久婷婷| 亚洲国产欧美在线人成| 亚洲日本在线天堂| 激情久久五月天| 精品免费视频123区| 欧美日韩久久久一区| 国产精品欧美久久久久无广告 | 成人久久18免费网站麻豆| 久久综合九色欧美狠狠| 欧美一区二区视频在线观看2022| 亚洲免费电影在线| 成人午夜激情片| 亚洲区一区二区三区| 国产视频在线观看一区二区三区 | 91亚洲精华国产精华精华液| 色综合天天综合网天天狠天天 | 亚洲18女电影在线观看| 91小视频在线免费看| 91福利在线播放| 亚洲天堂久久久久久久| 国产精品一品视频| 亚洲不卡1区| 中文一区在线播放| 国产麻豆91精品| 亚洲精品国产精品久久| 日本一区二区动态图| 国产一区二区三区综合| 欧美成人精品福利| 国产精品精品国产色婷婷| 国产一区二区不卡在线| 日韩av在线电影观看| 久久一二三国产| 久久精品国产免费| 欧美精品成人一区二区在线观看| 精品国产免费一区二区三区香蕉| 日韩**一区毛片| 精品亚洲欧美日韩| 日韩欧美成人一区| 久久精品国产亚洲一区二区三区| 欧美黑人xxxxx| 国产欧美一区视频| 高清视频一区二区| 欧日韩精品视频| 亚洲小说欧美激情另类| 国产九色精品| 精品国产乱码久久| 国产成人午夜99999| 一区二区在线观看网站| 亚洲三级视频在线观看| 91嫩草视频在线观看| 欧美一区二区三区在线观看| 日本亚洲欧美天堂免费| 蜜桃臀一区二区三区| 国产人久久人人人人爽| 高清在线成人网| 欧美三级三级三级爽爽爽| 午夜精品福利久久久| 久久99精品久久久久久水蜜桃 | 成人午夜在线免费| 欧美色网站导航| 欧美国产激情二区三区| 亚洲成va人在线观看| 国产一区二区三区高清视频| 欧美成人一级视频| 国产最新精品免费| 在线观看中文字幕不卡| 五月天亚洲精品| 日本一区免费看| 亚洲欧美另类久久久精品| 5566中文字幕一区二区| 精品少妇一区二区三区在线视频 | 亚洲欧美日韩国产手机在线 | 亚洲欧美久久234| 亚洲精品免费在线| 国新精品乱码一区二区三区18| 国产亚洲污的网站| 99视频一区二区| 337p日本欧洲亚洲大胆色噜噜| 国产黄色成人av| 69堂国产成人免费视频| 激情深爱一区二区| 欧美中文字幕亚洲一区二区va在线| 丝袜美腿亚洲一区二区图片| 亚洲制服中文| 石原莉奈一区二区三区在线观看| 亚洲成色最大综合在线| 亚洲成人动漫av| 色综合久久综合网97色综合 | 色综合久久天天综合网| 天天做天天摸天天爽国产一区 | 日韩欧美一二三区| 久久精品国产综合精品 | 国产精品亲子伦对白| 高清不卡一区二区三区| 欧美国产一区二区在线观看| 高清免费日韩| 国产精品萝li| 蜜桃在线一区二区三区精品| 一区二区三区精品| 视频一区视频二区视频| 日韩激情视频网站| 欧美视频日韩视频| 国产精品自拍三区| 欧美成人艳星乳罩| 91在线观看网站| 亚洲欧洲成人av每日更新| 免费精品视频一区| 香港成人在线视频| 91成人在线精品| 国产精品自拍一区| 久久先锋资源网| 精品一区二区国产| 亚洲福利一二三区| 中文字幕一区二区三区四区五区| 裸体歌舞表演一区二区| 在线播放日韩导航| 9色porny自拍视频一区二区| 国产精品色婷婷| 欧美中日韩免费视频| 日本系列欧美系列| 在线播放91灌醉迷j高跟美女| aaa亚洲精品| 1000精品久久久久久久久| 亚洲7777| 黄色日韩三级电影| 精品国产伦一区二区三区观看体验| 99视频在线免费观看| 一区二区三区欧美久久| 色婷婷香蕉在线一区二区| 国产成人精品亚洲日本在线桃色| 久久免费精品国产久精品久久久久| 国产在线观看一区| 视频在线观看91| 欧美一区二区成人6969| 成人av片网址| 亚洲成av人片一区二区梦乃| 欧美日韩成人激情| 91福利入口| 亚洲一区二区精品久久av| 欧美日韩一区三区| 91麻豆精品视频| 亚洲一区二区五区| 欧美福利电影网| 国产精品久久精品视| 午夜欧美一区二区三区在线播放| 欧美老年两性高潮| 操人视频欧美| 污片在线观看一区二区| 日韩欧美你懂的| 鲁丝一区鲁丝二区鲁丝三区| 久草精品在线观看| 国产亚洲福利社区一区| 日韩经典在线视频| 国产乱码精品一区二区三| 亚洲国产经典视频| 色妹子一区二区| 91精品久久久久久蜜桃| 亚洲成av人片| 精品嫩草影院久久| 日本一区不卡| 国产成人免费视频网站高清观看视频| 国产精品国产自产拍高清av王其| 欧洲另类一二三四区| 不卡视频一区二区三区| 日韩av不卡在线观看| 久久久亚洲精华液精华液精华液 | 国产伦精品一区二区三区视频孕妇 | 久久久久久黄色| 亚洲高清视频一区二区| 成人午夜碰碰视频| 亚洲一区二区欧美日韩| 日韩欧美视频在线| 午夜欧美一区二区三区免费观看| 成人午夜av在线| 亚洲高清免费在线| 26uuu久久综合| 一区二区三区视频在线播放| 99精品欧美一区二区蜜桃免费| 亚洲高清中文字幕| 久久久久国产一区二区三区四区| 一区二区不卡在线| 91精品黄色| 久久99精品久久久久|