最真实的办公自动化案例!
在數據分析的日常工作中,除了Excel數據的清洗,最常見的就是pdf、word、ppt等場景下的數據清洗,這種其實還有一個更高大上的名字,叫:辦公自動化。
很多時候由于辦公自動化場景下的數據是不規整的,所以在進行數據分析之前首要的就是進行數據提取。
例如,小一的朋友『長河』在實際工作中遇到的真實問題:
雖然我自己對word的操作不是很熟悉,但是我也在思考過后提供了自己的解決方法:
由于我自己對于PDF的數據提取比較擅長,也曾經寫過相關的操作文檔:Python辦公自動化之PDF的詳細操作(全),所以如果原始數據是pdf,那我就會按照上面我說的方法進行操作
但是長河他自己已經搞定了pdf的轉換,那問題就變成了多個word的數據提取。
下面的文章就是他自己在實現過程中的真實思路,部分數據比較敏感,文中已經打碼,但是不影響實際的閱讀和練手
這個也是在實際工作中比較常遇到的問題,希望大家下次遇到的時候都能游刃有余
以下是『長河』投稿的正文:
1. 問題來源
最近面臨的一個問題是從word中讀取表格數據,然后整理成excel格式。
如下所示:
word表格1,已脫敏處理如果表格不是很多,只有幾張表,完全手動處理就好,但是如果有140張表,9年的數據,該怎么處理呢?
這個時候需要程序來幫我們自動化解決了。
2.?解決問題
明確問題之后,我們接下來需要解決問題。
如果要從word中提取表格,常用的包有docx , 對提取中的數據進行規范處理,需要使用pandas
2.1 明確數據的行和列
如果要提取word表格中的行和列,則需要明白這個表格到底有多少行和列,然后再根據具體行和列進行數據的提取。
該部分內容可以參看B站的上的一些視頻,用Python操作Word
代碼如下:
from?docx?import?Documentdoc?=?Document('one.docx') tables?=?doc.tables table?=?tables[0]??#?表示讀取的第一張表#?查看一下多少行,多少列 print(len(table.rows),len(table.columns))輸出結果為:
5?14說明我們提取的表格信息是一個5行14列的數據。接下來需要思考,每一行每一列是什么樣子。
我們這里以第5行第2列為例進行說明:
繼續寫入代碼為:
print(table.cell(4,1).text)輸出結果為:
13905 270 5583 1528 1791 2315 2439 ...經過不斷地嘗試,我們終于知道自己需要的數據在什么地方了。
考慮到表頭的太過于復雜,不好定位,需要自己重新寫表頭信息即可,我們需要的是整個學校的數據,也就是下圖中的部分
提取表格1對應的數據2.2 數據提取
接下來進行數據提取:
list1?=?[]??#?定義一個空的列表存儲數據 for?row?in?range(4,len(table.rows)):for?column?in?range(len(table.columns)):list1.append(table.cell(row,column).text) print(len(list1)) print(list1)提取出來的數據是一串很長的列表,輸出結果為:
14 ['--大學\--大學\--大學\---大學\n????----\n2186588\n203224\n146649\n329602\n214014\n299323\n47413\n71033']接下來進行迭代,轉化成 [[],[],[]] 的形式
values?=?[] for?i?in?list1:i?=?i.split('\n')values.append(i) print(values)結果處理完成,結果如下:
[['xx大學',?'xxxx大學',?'xx大學',?---'xxxx大學'],---?['2186588',?'203224',?'146649',?'329602',?'214014',?'299323',?'47413',?'71033']]2.3 轉成 DataFrame格式
前面已經把values整理好了,接下來重新整理表頭信息即可:
colums?=?['xx','xx','xx'] data_part1?=?pd.DataFrame(values,columns).T print(data_part1.head())輸出結果為:
學校名稱???????xxxxxx-??...????????xxxx??????xxxxxxx 0????XX大學??????????13905??...????????46526?????2222470 1????XX大學???????????270??...????????????0???????67822 2????XX大學???????????5583??...???????331010?????3557540 3????XX大學???????????1528??...????????12826??????544980 4????XX大學???????????1791??...?????????1270??????844921[5?rows?x?14?columns]考慮到一個word文件有兩張表,第二張表的數據結構如下:
word表格2,已脫敏處理第二張表的表頭與第一張表有所不同,處理方式一樣,直接上代碼即可:
table?=?tables[1] for?row?in?range(3,?len(table.rows)):for?column?in?range(len(table.columns)):table2.append(table.cell(row,?column).text) for?h?in?table2:h?=?h.split('\n')values2.append(h) data2?=?pd.DataFrame(values2,column2).Tdata?=?pd.concat([data1,data2],axis?=1)2.4 完整地處理一張表
一張完整的word有兩張表,所以需要使用一個判斷條件進行處理,將其分為奇數位表和偶數位表,其判斷依據是某數除以2余數是否為 0,
具體的代碼如下:
import?pandas?as?pd from?docx?import?Document column1?=?['xx','xx','xx','xx','xx'] column2?=?['xx','xx','xx','xx','xx']for?t?in?range(len(tables)):if?t?%?2?==?0:table1?=?[]value1?=?[]table?=?docx.tables[t]for?row?in?range(4,?len(table.rows)):for?column?in?range(len(table.columns)):table1.append(table.cell(row,?column).text)for?j?in?table1:j?=?j.split('\n')value1.append(j)data1?=?pd.DataFrame(value1,?column1).Tif?t?%?2?==?1:table2?=?[]value2?=?[]table?=?docx.tables[t]for?row?in?range(3,?len(table.rows)):for?column?in?range(len(table.columns)):table2.append(table.cell(row,?column).text)for?h?in?table2:h?=?h.split('\n')value2.append(h)data2?=?pd.DataFrame(value2,column2).T data?=?pd.concat([data1,data2],axis?=1)2.5 完整地處理多張表
如果是處理多張表,則需要設置路徑,然后在具體的路徑中進行處理
具體的代碼如下:
import?pandas?as?pd from?docx?import?Document import?os column1?=?['xx','xx','xx','xx','xx'] column2?=?['xx','xx','xx','xx','xx']#?設置路徑 path?=?os.listdir('E:\one-two') #?print(path) for?i?in?range(len(path)):docx?=?Document('E:\one-two\{}'.format(path[i]))#?print('第{}表'.format(i+1),docx)tables?=?docx.tablesfor?t?in?range(len(tables)):if?t?%?2?==?0:table1?=?[]value1?=?[]table?=?docx.tables[t]for?row?in?range(4,?len(table.rows)):for?column?in?range(len(table.columns)):table1.append(table.cell(row,?column).text)for?j?in?table1:j?=?j.split('\n')value1.append(j)data1?=?pd.DataFrame(value1,?column1).Tif?t?%?2?==?1:table2?=?[]value2?=?[]table?=?docx.tables[t]for?row?in?range(3,?len(table.rows)):for?column?in?range(len(table.columns)):table2.append(table.cell(row,?column).text)for?h?in?table2:h?=?h.split('\n')value2.append(h)data2?=?pd.DataFrame(value2,column2).Tdata?=?pd.concat([data1,data2],axis?=1)print('正在保存{}'.format(i+1))data.to_excel('E:\one-two\{}.xlsx'.format(i),index=False)最后的輸出結果為:
最終成效3. 總結
學習編程會遇到很多問題和困惑。但是這個也是提高自己編程技術的關鍵所在。不斷地探索,看B站視頻,請教大佬,然后不停地print看輸出結果,就會得到自己想要的東西!
感謝小一前輩提供的思路,筆芯筆芯!
一個word一個word的處理,這樣反而能提高效率!
推薦閱讀
牛逼!Python常用數據類型的基本操作(長文系列第①篇)
牛逼!Python的判斷、循環和各種表達式(長文系列第②篇)
牛逼!Python函數和文件操作(長文系列第③篇)
牛逼!Python錯誤、異常和模塊(長文系列第④篇)
總結
以上是生活随笔為你收集整理的最真实的办公自动化案例!的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 2021年互联网公司“死亡”名单!(附清
- 下一篇: PandasGUI:使用图形用户界面分析