Skip to content

Instantly share code, notes, and snippets.

@wildart

wildart/doc_parser.py

Last active Jul 29, 2018
Embed
What would you like to do?
parser-rosstat-doc
# Requires to install pandas & pywin32, and of course MS Word installed.
import sys
import os
import win32com.client
import pandas as pd
import re
import numpy as np
JUNK_SYMBOLS = r'[\x07|\t|\x0b|\r|\x0c]'
def get_float(s):
if len(s) == 0:
return np.nan
# replace comma
s = s.strip().replace(',', '.')
s = re.sub(r'[^\d|.|)]', '', s)
if len(s) == 0:
return np.nan
if s[-1] == ')':
s = s[:-2]
try:
return float(s)
except ValueError:
return np.nan
def clean_index(scell):
scell = re.sub(r'\s{2,}', ' ', scell) # replace multiple spaces
scell = scell.replace('\n', ' ') # remove new lines
#try to find '/' for english part
sidx = scell.find('/')
if sidx < 0:
return None
idx = scell.split('/')[-1].strip() # get english part
return idx
def find_first_filled_col(rng):
i = 1
while True:
cl = rng.Cells(i)
txt = cl.Range.Text
if len(re.sub(JUNK_SYMBOLS, '', txt).strip()) > 0 and cl.ColumnIndex == 1:
return i
i += 1
docname = 'tab.doc' if len(sys.argv) < 2 else sys.argv[1]
docfile = os.path.realpath(docname)
# open word
word = win32com.client.Dispatch("Word.Application")
#word.visible = True
word.visible = False
wb = word.Documents.Open(docfile)
doc = word.ActiveDocument
# setup data frame
indexed = ['Category', 'Year']
header = ['YTD', 'Q1', 'Q2', 'Q3', 'Q4', 'Jan.', 'Feb.', 'Mar.', 'Apr.', 'May', 'June', 'July', 'Aug.', 'Sept.', 'Oct.', 'Nov.', 'Dec.']
df = pd.DataFrame(columns=indexed+header)
df.set_index(indexed, inplace=True)
global_index = []
try:
# loop through tables
total_tables = len(doc.Tables)
for tidx in range(0, total_tables-1):
print(tidx)
table = doc.Tables[tidx]
rc = table.Rows.Count
cc = table.Columns.Count
rng = table.Range
i = find_first_filled_col(rng)
index = []
row = []
c = 1
cl = rng.Cells(i)
for i in range(i, rng.Cells.Count):
clnext = rng.Cells(i+1)
txt = re.sub(JUNK_SYMBOLS, '', cl.Range.Text.strip()) # remove special symbols
# if len(txt.strip()) == 0: # if cell is empty
# cl = clnext
# continue
# check description of table part to construct index
if cl.ColumnIndex == 1:
if re.match(r'^(\d+\.\d+\.|\D)+', txt) is not None:
if re.match(r'^(\d+\.\d+\.\s)+', txt) is not None: # match subsection <N.N.>
print('cat: {0}'.format(txt))
global_index = []
sidx = clean_index(txt)
print('index: {0}'.format(sidx))
if sidx is not None:
index.append(sidx)
else:
try:
year = int(txt[:4])
row.append(year)
except ValueError:
print("c:{0} = {1}".format(i, txt))
cl = clnext
continue
# data
if len(index) > 0: #merge with global index
if len(global_index) == 0:
global_index = index.copy()
elif len(global_index) == 1:
global_index += index
else:
global_index[-len(index):] = index
print(global_index)
index = []
val = get_float(txt)
if len(row) == 0 and val is np.nan:
cl = clnext
continue
else:
row.append(val)
c += 1
if c == cc: # reached last column
if row[0] is not np.nan:
midx = (', '.join(global_index), int(row[0]))
if cc == 6:
rr = row[1:] + [np.nan for i in range(0, len(header)-cc+1)]
elif cc == 13 or cc == 14:
rr = [np.nan for i in range(0, len(header)-cc+1)] + row[1:]
else:
rr = row[1:]
try:
df.loc[midx,:] = rr
except:
print(midx)
print(rr)
row = []
c = 1
cl = clnext
if len(row) == 0: # drop last cell that does not fit into row
continue
# last cell
txt = re.sub(JUNK_SYMBOLS, '', cl.Range.Text)
row.append(get_float(txt))
try:
midx = (', '.join(global_index), int(row[0]))
except:
print(row)
if cc == 6:
rr = row[1:] + [np.nan for i in range(0, len(header)-cc+1)]
elif cc == 13 or cc == 14:
rr = [np.nan for i in range(0, len(header)-cc+1)] + row[1:]
else:
rr = row[1:]
df.loc[midx,:] = rr
except:
print("Unexpected error:", sys.exc_info()[0])
raise
finally:
df.to_msgpack("tab.msgpack")
word.Quit(0)
>>> pd.read_msgpack("tab.msgpack")
YTD Q1 Q2 Q3 Q4 Jan. Feb. Mar. Apr. May June July Aug. Sept. Oct. Nov. Dec.
Categoty Year
Gross domestic product1), GDP, bln rubles 1999 4823.0 901.0 1102.0 1373.0 1447.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2000 7306.0 1527.0 1697.0 2038.0 2044.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2001 8944.0 1901.0 2105.0 2488.0 2450.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2002 10831.0 2262.0 2529.0 3013.0 3027.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2003 13208.0 2851.0 3102.0 3600.0 3655.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2004 17027.0 3516.0 3972.0 4594.0 4945.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2005 21610.0 4459.0 5078.0 5845.0 6228.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2006 26917.0 5793.0 6368.0 7276.0 7480.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2007 33248.0 6780.0 7768.0 8903.0 9797.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2008 41277.0 8878.0 10238.0 11542.0 10619.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2009 38807.0 8335.0 9245.0 10411.0 10816.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2010 46308.0 9996.0 10977.0 12086.0 13249.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2011 59698.0 12844.0 14314.0 15663.0 16877.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2012 66927.0 14925.0 16149.0 17442.0 18411.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2013 71017.0 15892.0 17015.0 18543.0 19567.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2014 79200.0 17139.0 18884.0 20407.0 21515.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2015 83233.0 18210.0 19284.0 21294.0 22016.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2016 86044.0 18561.0 19979.0 22190.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
Gross domestic product1), percent of correspond... 1999 106.4 98.1 103.1 111.4 112.0 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2000 110.0 111.4 110.2 110.5 108.2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2001 105.1 104.7 105.0 106.0 104.5 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2002 104.7 103.8 104.4 104.4 106.2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2003 107.3 107.5 107.9 106.1 107.6 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2004 107.2 107.2 108.0 107.3 106.2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2005 106.4 105.6 106.0 106.0 107.8 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2006 108.2 107.3 108.1 108.2 108.9 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2007 108.5 108.1 108.6 108.2 109.2 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2008 105.2 109.2 107.9 106.4 98.7 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2009 92.2 90.8 88.8 91.4 97.4 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
2010 104.5 104.1 105.0 103.8 105.1 NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN NaN
... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ... ...
Consumer price index percent of previous month,... 2004 NaN NaN NaN NaN NaN 103.3 101.9 100.4 100.6 100.1 101.3 101.5 98.4 98.4 101.1 102.1 103.1
2005 NaN NaN NaN NaN NaN 102.9 102.2 102.8 102.8 101.8 101.4 100.2 95.9 96.5 100 101.8 102.2
2006 NaN NaN NaN NaN NaN 104.3 105.5 101.2 99.8 100.5 100.4 101.8 96.6 96.1 99.6 101.5 102.1
2007 NaN NaN NaN NaN NaN 102.2 101.2 101.2 100.8 102.2 104.8 103.6 96 99 104 102.8 102.7
2008 NaN NaN NaN NaN NaN 104.3 103.3 102.7 103.9 104.1 100.9 98.8 96.3 98.5 101.4 101.3 101.1
2009 NaN NaN NaN NaN NaN 102 101.5 100.6 100.4 101.2 101.4 101.5 96.6 96.2 98.2 100.3 101.1
2010 NaN NaN NaN NaN NaN 102.4 102.2 101.4 100.4 101.5 101.2 100.4 100.7 103 100.9 102.2 104.2
2011 NaN NaN NaN NaN NaN 107.5 102 100.7 99.8 98.8 98.4 97.4 93.5 95.9 99.2 100.4 100.9
2012 NaN NaN NaN NaN NaN 100.7 100.8 100.7 100.4 101 103.8 102.1 97.6 98.3 100 100.8 101.5
2013 NaN NaN NaN NaN NaN 101.9 101.2 100.9 102.1 103.8 103.2 99.7 95.8 97.2 101.6 101.2 101.2
2014 NaN NaN NaN NaN NaN 102.2 102.6 102.7 101.9 103.1 101.4 96.9 94.9 99.3 101.6 103.1 105.1
2015 NaN NaN NaN NaN NaN 108.3 103.8 101.2 100.3 101 99.2 99.3 95.2 98.1 100 100.9 101.2
2016 NaN NaN NaN NaN NaN 101.4 100.6 100.2 100.6 101.7 102.1 100.1 97.3 97.8 100.2 100.9 100.9
Consumer price index percent of previous month,... 2000 NaN NaN NaN NaN NaN 102.2 102.5 101.9 102.1 105.1 109.4 111.5 107.8 105 106.4 109.6 113.2
2001 NaN NaN NaN NaN NaN 104.6 108.1 110.2 112.8 116.8 120.2 117.9 113.5 111 111.7 114.6 118.8
2002 NaN NaN NaN NaN NaN 105.1 106.2 105.9 107.5 111.7 110.9 110.7 107.2 104.2 105 108.4 112.8
2003 NaN NaN NaN NaN NaN 104 106.1 106.8 108.6 109.6 111 111.1 104.9 102.1 102.9 105.1 107.6
2004 NaN NaN NaN NaN NaN 103.3 105.3 105.7 106.3 106.5 107.8 109.4 107.7 105.9 107.1 109.4 112.7
2005 NaN NaN NaN NaN NaN 102.9 105.2 108.1 111.1 113.1 114.7 115 110.3 106.4 106.4 108.3 110.7
2006 NaN NaN NaN NaN NaN 104.3 110 111.3 111.1 111.6 112.1 114 110.1 105.9 105.4 107 109.2
2007 NaN NaN NaN NaN NaN 102.2 103.4 104.7 105.5 107.9 113.1 117.1 112.4 111.3 115.8 119 122.3
2008 NaN NaN NaN NaN NaN 104.3 107.7 110.6 114.9 119.6 120.6 119.2 114.8 113.1 114.7 116.2 117.5
2009 NaN NaN NaN NaN NaN 102 103.5 104.1 104.6 105.9 107.3 108.9 105.2 101.1 99.3 99.6 100.7
2010 NaN NaN NaN NaN NaN 102.4 104.7 106.2 106.6 108.2 109.5 110 110.8 114.1 115.2 117.7 122.7
2011 NaN NaN NaN NaN NaN 107.5 109.7 110.4 110.3 109 107.2 104.4 97.6 93.5 92.8 93.2 93.9
2012 NaN NaN NaN NaN NaN 100.7 101.5 102.2 102.6 103.7 107.6 109.9 107.3 105.4 105.4 106.2 107.8
2013 NaN NaN NaN NaN NaN 101.9 103 103.9 106.1 110.1 113.6 113.3 108.6 105.5 107.2 108.5 109.9
2014 NaN NaN NaN NaN NaN 102.2 104.8 107.7 109.7 113.1 114.7 111.2 105.5 104.7 106.4 109.8 115.3
2015 NaN NaN NaN NaN NaN 108.3 112.4 113.7 114.1 115.2 114.3 113.5 108 106 106 106.9 108.2
2016 NaN NaN NaN NaN NaN 101.4 102.1 102.2 102.9 104.6 106.7 106.8 103.9 101.6 101.8 102.7 103.5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment