
利用Camelot識(shí)別pdf文件中的表格,除了必須加上flavor = 'stream' ,以及指定 table_areas識(shí)別區(qū)域之外,補(bǔ)充下在識(shí)別pdf表格時(shí)遇到的如多行數(shù)據(jù)、上下標(biāo)等情況時(shí)的參數(shù)設(shè)置。
Camelot的安裝及基本用法見(jiàn)Python解析PDF表格——PDFPlumber vs Camelot,
'pages'指定識(shí)別的頁(yè)碼

世衛(wèi)組織報(bào)告中的表格位于第3-6頁(yè)(如下圖),指定識(shí)別的頁(yè)碼用'pages'參數(shù)。

增大'edge_tol'自動(dòng)擴(kuò)大識(shí)別區(qū)域
默認(rèn)參數(shù)下,Camelot未能識(shí)別出全部的表格區(qū)域。如上圖,第3頁(yè)只識(shí)別出了15行,遠(yuǎn)小于表格所在頁(yè)的行數(shù)。
除了在Python解析PDF表格——PDFPlumber vs Camelot介紹的用camelot.plot()命令查看表格所在區(qū)域然后再指定table_areas來(lái)處理外,也可以將'edge_tol'參數(shù)指定為一個(gè)較大的數(shù)字,如本例中將edge_tol = 500,讓Camelot自動(dòng)擴(kuò)大識(shí)別區(qū)域。
camelot.plot(tables[0], kind='contour')
table_areas=['1,680,600,1']

'row_tol'識(shí)別包含多行文字的表格行

本例中,表頭和個(gè)別數(shù)據(jù)條,單元格中包含了多行文本,有可能需要將多行文字自動(dòng)合并,此時(shí)涉及到'row_tel'參數(shù)的調(diào)整。將該參數(shù)數(shù)值增大,Camelot會(huì)自動(dòng)將多行文字合并,但這樣也有可能帶來(lái)意想不到的結(jié)果。


如上圖,指定row_tol = 40雖然表頭部分的多行文字被自動(dòng)合并為了一行,合并后的文字用'\n'連接;但下面的數(shù)據(jù)條部分,也被Camelot給合并到了一起,這顯然不是我們希望看到的結(jié)果。所以對(duì)于'row_tol'參數(shù)一定是要視情況靈活處理,也提醒我們?cè)谧R(shí)別表格時(shí)需要隨時(shí)檢查中間結(jié)果是否識(shí)別正確。


本例中一些國(guó)家名稱(chēng)文字較長(zhǎng),如伊朗在表格中為Iran (Islamic Republic of),被分作兩行。默認(rèn)設(shè)置下,數(shù)據(jù)所在單元格和國(guó)家名稱(chēng)一共被識(shí)別為3行;而適當(dāng)加大row_tol后(將'row_tol'指定為12),識(shí)別的結(jié)果數(shù)據(jù)所在單元格自動(dòng)向上融合到了國(guó)家名稱(chēng)所在列的第一行。這樣更便于在后續(xù)處理時(shí)中修正國(guó)家名稱(chēng)。
'flag_size'是否識(shí)別上(下)標(biāo)文字
當(dāng)單元格中存在上標(biāo)時(shí),指定'flage_size = True',Camelot會(huì)在上標(biāo)下標(biāo)中自動(dòng)加上<s> </s>標(biāo)簽,如下圖所示。


'split_text'分割字符串
'flage_size參數(shù)用于指定是否分割識(shí)別的字符串,如下圖,'flage_size = True'時(shí),表格外的字符串被分割后分到了各列。在本例中,這種自動(dòng)分割的結(jié)果看起來(lái)并不是必須的,因?yàn)槲覀兏信d趣的是表格內(nèi)的數(shù)據(jù)部分,表格以外的文字本就會(huì)舍去。

'strip_text'自動(dòng)替換文字
'strip_text參數(shù)用于指定是否分割識(shí)別的字符串,如下圖,strip_text= '??§\n(<>)(</).'*,Camelot會(huì)在識(shí)別出文字后,自動(dòng)刪去類(lèi)似上下標(biāo)標(biāo)準(zhǔn)'<s>'、'</s>',跨行單元格的'\n'等等。

pandas.to_numeric轉(zhuǎn)化識(shí)別結(jié)果轉(zhuǎn)換為數(shù)字型
Camelot識(shí)別后結(jié)果,各國(guó)的疫情數(shù)據(jù)是個(gè)字符串而不是數(shù)字,因此還需要利用pandas.to_numeric,或是astype(int)將數(shù)據(jù)類(lèi)型轉(zhuǎn)換為數(shù)字型。

本例中上述參數(shù)設(shè)置如下。
table_p3 = camelot.read_pdf(r'./20200318-sitrep-58-covid-19.pdf', flavor='stream',
pages='3', flag_size=True, row_tol=10, table_areas=['1,680,600,1'],#edge_tol=500,
split_text=False, strip_text='*??§\n(<>)(</).')
最后用Pyecharts繪制地圖,結(jié)果如下:

結(jié)論
- 對(duì)于有文字和表格混合排版的頁(yè)面,建議采用指定table_areas指定表格識(shí)別區(qū)域,而不是增大edge_tol,來(lái)處理。
- row_tol的設(shè)置需要根據(jù)待識(shí)別表格的情況靈活選擇,除非確有必要,不建議將該參數(shù)設(shè)置為過(guò)大的數(shù)數(shù)值。
- 當(dāng)單元格中有上下標(biāo)時(shí),指定**flage_size = True **更為穩(wěn)妥,否則有可能將類(lèi)似
誤做
,造成數(shù)據(jù)不準(zhǔn)確。
- split_text、strip_text根據(jù)表格的具體情況設(shè)定。
- 隨時(shí)檢查中間結(jié)果!隨時(shí)檢查中間結(jié)果!隨時(shí)檢查中間結(jié)果!