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