Как извлечь родительские и дочерние данные из текстового файла, который не является табличным? - PullRequest
0 голосов
/ 25 сентября 2019

У меня есть текстовый файл в кодировке UTF-8, который содержит выходные данные отчета, которые я хотел бы поместить во фрейм данных.У меня проблема в том, что данные не являются табличными, они состоят из родительских строк и дочерней строки, заголовков страниц и т. Д.

Это пример схемы файла, в полном файле около 2000 + записей

ACME LTD (SP)                       Report for Mexico                       Time 14:18:11     Date  04082019                                                                                    
Mexico                                                                                     *********/JOEOD Page           1                                                                                 

Cnno        Acct no         Tax number                  Address                                     

1       ABC3415         899111752                   Kellys Hair ONE ST JOHNS CHURCHYARD ED45 8LP LONDON                                     

PstDte          Docno           DocDte      Reference no            ClgDte  WT  code        Invoice amnt       Base amount   tax     Net amount  T  x-exempt amt    

    tax type:                       W1      tax code:                   WA                      

80519           5100002076          70519       20006874            50719   WA          1156961002  1156961003  76311439    1156961002  -1  
10619           5100002673          70519       20007095            50719   WA          2147567637  2147567637  144956394   2147567637  0   
******                                              WA          3304528639  330452864   221267833   3304528639  -1  

                                                ** ****         3304528639  330452864   221267833   3304528639  -1  


2       BFG4919         7880487069                  SPA LTD OHNSON HOUSE GREENBY SQHH1 3DF READING                                      

    tax type:                       W1      tax code:                   WA                      

30619           5100002672          30619       90331014            20719   WA          2260302 1883585 1260708 1883585 376717  
30619           5100002681          30619       90331015            20719   WA          73519295    61266079    4100618 61266079    12253216    
10719           5100002679          30619       90331016            20719   WA          105593207   87994339    5719633 87994339    17598868    
10719           5100002680          30619       90331017            20719   WA          82808594    69007162    4485466 69007162    13801432    
10719           5100003245          10719       90332783            300719  WA          80358636    6696553 4447229 6696553 13393106    
10719           5100003246          10719       90332782            300719  WA          102408262   85340218    5667505 85340218    17068044    
10719           5100003247          10719       90332781            300719  WA          73498752    6124896 4067587 6124896 12249792    
10719           5100003248          10719       90332780            300719  WA          22784614    18987178    1260952 18987178    3797436 
******                                              WA          56357438    469645316   31009698    469645316   93929064    

                                                ** ****         56357438    469645316   31009698    469645316   93929064    


3       KLU5437         6781754415                  BIRDS SERVICES LIMITED GREEN HOUSE REDCAR INDUSTEC4L 4HJ LONDON                                     

    tax type:                       CS      tax code:                   CS                      

110619          5100002956          120619      1975674         90719   CS          1839932 17523288    91166   17523288    876032  
10719           5100003373          120619      1975677         120719  CS          78940756    705990901   35886346    754108083   83416659    
10719           5100003391          120619      1975675         120719  CS          643442103   61280197    31149443    61280197    30640133    
******                                              CS          1451248983  1336316159  67947449    1384433341  114932824   

    tax type:                       W1      tax code:                   WA                      

110619          5100002956          120619      1975674         90719   WA          1839932 17523288    1185159 17523288    876032  
10719           5100003373          120619      1975677         120719  WA          78940756    754108084   49831859    754108083   35299476    
10719           5100003389          60619       1975671         120719  WA          368898403   368898403   24377001    368898403   0   
10719           5100003391          120619      1975675         120719  WA          643442103   61280197    40494277    61280197    30640133    
10719           5100003394          110619      1975678         120719  WA          1421290282  1421290283  93919609    1421290282  -1  
10719           5100003513          120619      1975676         190719  WA          172718664   172718664   11434027    172718664   0   
10719           5100003626          210619      1975693         260719  WA          276901444   25751819    17101966    276901444   19383254    
******                                              WA          3691057776  3604858882  238343898   3624242134  86198894    

    tax type:                       X1      tax code:                   XA                      

110619          5100002956          120619      1975674         90719   XA          1839932 17523288    91167   17523288    876032  
10719           5100003373          120619      1975677         120719  XA          78940756    754108084   383322  754108083   35299476    
10719           5100003389          60619       1975671         120719  XA          368898403   368898403   1875154 368898403   0   
10719           5100003391          120619      1975675         120719  XA          643442103   61280197    3114945 61280197    30640133    
10719           5100003394          110619      1975678         120719  XA          1421290282  1421290283  7224586 1421290282  -1  
10719           5100003513          120619      1975676         190719  XA          172718664   172718664   879541  172718664   0   
10719           5100003626          210619      1975693         260719  XA          276901444   25751819    1315536 276901444   19383254    
******                                              XA          3691057776  3604858882  18334149    3624242134  86198894    
ACME LTD (SP)                       Report for Mexico                       Time 14:18:11     Date  04082019                                                                                    
Mexico                                                                                     *********/JOEOD Page           2                                                                                     
Cnno        Acct no         Tax number                  Address                                     

3       KLU5437         6781754415                  BIRDS SERVICES LIMITED GREEN HOUSE REDCAR INDUSTEC4L 4HJ LONDON                                     

PstDte          Docno           DocDte      Reference no            ClgDte  WT  code        Invoice amnt       Base amount   Withholdtax     Net amount  T  x-exempt amt    


                                                ** ****         3691057776  8546033923  324625496   3624242134  -4854976147 


4       KLD15935            837960557                   BOJACK GROUP LTD HORSEMAN HOUSE SHADWELLGH12 3BB ABERDEEN                                       

    tax type:                       W1      tax code:                   WA                      

10719           5100003296          290519      82620012754         90719   WA          6863606446  6863606446  443122606   6863606446  0   
10719           5100003654          210619      82620013425         260719  WA          5854587092  585458709   381911219   5854587092  2   
******                                              WA          12718193538 12718193536 825033825   12718193538 2   

                                                ** ****         12718193538 12718193536 825033825   12718193538 2   


5       HDH943859                               Rover Energy Schweiz AG SWIZSTRASSE 345 1005 ZURICH                                     

    tax type:                       W1      tax code:                   WA                      

10719           5100003613          20419       2963427         260719  WA          2893481234  2893481234  190177614   2893481234  0   
10719           5100003614          20419       2963426         260719  WA          2893481234  2893481234  190177614   2893481234  0   
******                                              WA          5786962468  5786962468  380355228   5786962468  0   

                                                ** ****         5786962468  5786962468  380355228   5786962468  0   

Я хочу отформатировать данные в следующую плоскую структуру

Cnno, Acct no, Tax number, Address, PstDte, Docno, DocDte, Reference no, clg date,tax type, WT code, Invoice amnt,Base amount,tax,Net amount,T  x-exempt amt

Честно говоря, кроме загрузки данных в фрейм данных и удаления пустых строк, я не продвинулся далеко.Я посмотрел, но не могу найти никаких похожих примеров, поэтому, если у кого-нибудь есть какие-либо учебные пособия по ссылкам, касающиеся подобных проблем извлечения данных, это было бы замечательно, или если у вас есть идеи о том, как справиться с этим, это было бы началом.

1 Ответ

0 голосов
/ 27 сентября 2019

Таким образом, после того, как я рассмотрю более подход, который я использовал для очистки, выглядит следующим образом:

Загрузка в df, заголовков нет, поэтому столбцы - это всего лишь 0,1,2 лота NaN и т. Д.

Удалите все столбцы, которые являются NaN

df2 = df.dropna(axis = 0, how ='all').copy()

Я хотел сохранить название компании, но не другие данные, такие как заголовок отчета или округ, поэтому разделите строку, чтобы удалитьтекст, который я не хотел, а затем создал маску для строк, содержащих Мексику, а затем отфильтровал df, чтобы удалить их

df2[0] = df2[0].str.split('  ').str[0]
mask = (df2[0] == 'Mexico')
df3 = df3[~mask].copy()

Затем использовал ffill, чтобы скопировать название компании в каждую строку df (тамявляются несколькими названиями компаний, отчет делает все записи для одной компании, затем для следующей и т. д.)

df3[0]=df3[0].fillna(method='ffill')

Столбец [1] содержит данные для родительской записи Cnno и дочерних записей Pstdte, эточисловые данные хранятся в виде текста, поэтому я отфильтровал этот столбец с помощью to_numeric, это удаляет все строки заголовков и номеров страниц, которые повторяются, хотя из данных остаются только родитель и потомокстрок.

df4 = df3[new_WHT2[[1]].apply(pd.to_numeric, errors='coerce').notnull().all(axis=1)].copy()

Затем я создал новый столбец 'Cnno' и заполнил его, используя

df4.loc[new_WHT3[1]<9999, 'Cnno'] = df4[1]

, и Cnno, и Pstdte являются числами, но поскольку Pstdte является "датой",минимальная длина равна 5, а Cnno никогда не превышает длину 4, поэтому я мог бы использовать это для разделения родительских и дочерних строк

Поскольку за каждой родительской строкой следуют ее дочерние элементы в кадре данных, я мог бы использовать ffill для'Cnno', чтобы скопировать родительский Cnno к его дочерним элементам, чтобы связать записи

df4['Cnno'] = df4['Cnno'].fillna(method='ffill')

Затем я создал родительский столбец для идентификации родительских записей (не обязательно)

df4['Parent'] = (df4[1]<9999).astype(int)

Затем я отфильтровал родительский столбец и скопировал данные в новый файл df, удалил все пустые данные, удалил старые данные для cnno в столбце [1] и добавил новые заголовки столбцов для остальных.Поскольку родительская строка повторяется при появлении новой страницы в исходном файле, было несколько строк с одинаковыми данными, поэтому я отбросил дубликаты, оставив только первую

Parent = df4[df4['Parent'] == 1].copy()
Parent = Parent.dropna(axis=1, how='all')
Parent = Parent.drop(Parent.columns[1] , axis=1)
Parent.columns = ['Company','Account No','Tax Code','Vendor Address','Cnno','Parent']
Parent.drop_duplicates(keep='first', inplace=True)

. Затем получим чистую dfтолько родительские записи

  Company, Account No, Tax Code, Vendor Address, Cnno, Parent
5 ACME Ltd, ABC3415, 899111752, Kellys Hair ONE ST JOHNS CHURCHYARD ED45 8LP LONDON, 1, 1 
18 ACME Ltd, BFG4919, 7880487069, SPA LTD OHNSON HOUSE GREENBY SQHH1 3DF READING, 2, 1 

Затем я в основном сделал то же самое с дочерними записями

Children = df4[df4['Parent'] != 1].copy()
Children = Children.dropna(axis=1, how='all')
Children.columns = ['Company','PstDte', 'DocNo','DocDte','Reference no','ClgDte','WT code','Invoice amnt','Base amount','tax','Net amount','T x-exempt amt','Cnno','Parent']

Это дало мне чистую df всех дочерних записей, затем я объединил родителя идочерние записи, используя ключ company и cnno

Final = pd.merge(Parent, Children,  how='left', left_on=['Company','Cnno'], right_on = ['Company','Cnno'])

После этого это был всего лишь случай форматирования каждого из столбцов даты и любых других битов форматирования, dtypes и т. д.

Final['PstDte'] = Final['PstDte'].apply(lambda x: pd.to_datetime(str(x), format='%d%m%y'))
...