利用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é)果!