In [1]:
import pandas as pd
import numpy as np
import glob
import re
import matplotlib.pyplot as plt
import os

In [2]:
%matplotlib inline

Some utility functions


In [3]:
def to_float(x):
    '''returns float value of x or NaN'''
    
    if x is np.nan:
        return x
    try:
        x = float(x)
    except (ValueError, UnicodeEncodeError, TypeError), e:
        print(x), e
        return np.nan
    else:
        return x
    
def replace_value(x, pattern):
    # there've got to be a better way
    try:
        missing = re.findall(pattern, str(x))
    except UnicodeEncodeError:
        return np.nan  # usually because of Thai words for "not tested"
    else:
        if missing:
            return np.nan
        else:
            return x

def replace_missing_value(dataframe, colnames):
    for pattern in ['\s+\-', '\-\s+', '\s+-\s+', '-']:
        dataframe[colnames] = dataframe[colnames].applymap(lambda x: replace_value(x, pattern))

def convert_to_float(dataframe, colnames):
    dataframe[colnames] = dataframe[colnames].applymap(to_float)

Load data from excel

Let's look at the data from January, 2551


In [4]:
years = []
for yr in ['2551', '2552', '2553', '2554', '2555']:
    months = []
    for f in glob.glob('data/community/%s/*xls' % yr):
        #print 'year: %s, month: %s' % (yr, f)
        try:
            df = pd.read_excel(f)
        except:
            print 'ERROR! year: %s, month: %s' % (yr, f)
        else:
            m = os.path.splitext(os.path.basename(f))[0]
            df['month'] = m
            df['year'] = yr
            months.append(df)
    years.append(months)

    #years.append(pd.concat(months, ignore_index=True))

In [5]:
new_col_names = [unicode(s) for s in ['ServiceNo', 'Location', 'HN',
                 'ServiceDate', 'Title', 'Age', 'Gender',
                 'Weight', 'Height', 'HeartRate', 'OldSystolic',
                 'HeartLungAbdomen', 'Smoke', 'LongTermSmoker', 'ExSmoker',
                 'Drink', 'LongTermDrinker', 'Disease',
                 'Stress', 'Medication', 'Exercise', '35YrMenstruation',
                 'MenopausePeriod', 'CauseOfMenopause', 'MenopauseMedication']]
new_col_names += months[0].columns[25:]

for months in years:
    for df in months:
        #df.rename(columns={'Systolic': 'OldSystolic'}, inplace=True)
        df.columns = new_col_names

In [6]:
for y, months in enumerate(years):
    for m, df in enumerate(months):
        #print(y, m)
        replace_missing_value(df, ['Glucose', 'Triglyceride', 'HDL-C',
                                    'OldSystolic', 'Weight', 'Height'])
        
        #some values have an extra forward slash, which is needed to be removed.
        df[['Systolic', 'Diastolic']] = df['OldSystolic'].str.replace('//', '/').str.split('/').apply(pd.Series)

        convert_to_float(df, ['Glucose', 'Triglyceride', 'HDL-C',
                              'Systolic', 'Diastolic', 'Weight', 'Height'])


133.8//131.5 invalid literal for float(): 133.8//131.5
EKG could not convert string to float: EKG
EKG could not convert string to float: EKG
EKG  could not convert string to float: EKG 
EKG  could not convert string to float: EKG 
       could not convert string to float: 
       could not convert string to float: 
77 , 89 invalid literal for float(): 77 , 89
68 , 81 invalid literal for float(): 68 , 81
115 , 125 invalid literal for float(): 115 , 125
77 , 89 invalid literal for float(): 77 , 89
68 , 81 invalid literal for float(): 68 , 81
115 , 125 invalid literal for float(): 115 , 125
EKG  could not convert string to float: EKG 
EKG  could not convert string to float: EKG 
EKG  could not convert string to float: EKG 
EKG  could not convert string to float: EKG 
132 H invalid literal for float(): 132 H
68 L invalid literal for float(): 68 L
52 L (Repeated) invalid literal for float(): 52 L (Repeated)
145 H invalid literal for float(): 145 H
132 H invalid literal for float(): 132 H
68 L invalid literal for float(): 68 L
52 L (Repeated) invalid literal for float(): 52 L (Repeated)
145 H invalid literal for float(): 145 H
437 (repeated) invalid literal for float(): 437 (repeated)
437 (repeated) invalid literal for float(): 437 (repeated)
52 (serum) invalid literal for float(): 52 (serum)
46 (serum) invalid literal for float(): 46 (serum)
52 (serum) invalid literal for float(): 52 (serum)
46 (serum) invalid literal for float(): 46 (serum)
EKG could not convert string to float: EKG
EKG could not convert string to float: EKG
EKG could not convert string to float: EKG
EKG could not convert string to float: EKG
No sample could not convert string to float: No sample
No sample could not convert string to float: No sample
 could not convert string to float: 

Calculate BMI


In [7]:
for months in years:
    for df in months:
        df['BMI'] = df['Weight']/(df['Height']/100.0)**2.0

In [8]:
new_years = []

for months in years:
    df = pd.concat(months, ignore_index=True)
    new_years.append(df)

In [9]:
bmis = []
gluc = []
trig = []
hdlc = []
systolic = []
diastolic = []
for yr in new_years:
    bmis.append(getattr(yr, 'BMI').tolist())
    gluc.append(getattr(yr, 'Glucose').tolist())
    trig.append(getattr(yr, 'Triglyceride').tolist())
    hdlc.append(getattr(yr, 'HDL-C').tolist())
    systolic.append(getattr(yr, 'Systolic').tolist())
    diastolic.append(getattr(yr, 'Diastolic').tolist())

In [10]:
def plot(data, title, ylim, outfile):
    fig = plt.figure(figsize=(8,6))
    plt.boxplot(data)
    plt.title(title, size=16)
    plt.ylim(ylim)
    plt.xticks(np.arange(len(new_years))+1, ['2551', '2552', '2553', '2554', '2555'])
    plt.savefig(outfile)

In [11]:
plot(bmis, 'BMI', (0,60), 'bmis.png')



In [12]:
plot(trig, 'Triglyceride', (0,800), 'trig.png')



In [13]:
plot(gluc, 'Glucose', (0,500), 'gluc.png')



In [14]:
plot(hdlc, 'HDL-C', (0,200), 'hdlc.png')



In [15]:
plot(systolic, 'Systolic', (0,300), 'systolic.png')



In [16]:
plot(diastolic, 'Diastolic', (0,200), 'diastolic.png')


Extract คลองใหม่ data


In [17]:
klongmai = set()
for y, months in enumerate(years):
    for m, df in enumerate(months):
        for e in df['Location']:
            if isinstance(e, unicode):
                if 'คลอง' in e.encode('utf-8'):
                    klongmai.add((y,m))

In [18]:
klongmai


Out[18]:
{(0, 6), (1, 4), (2, 4), (4, 5)}

Some statistics of all data


In [19]:
year_list = ['2551', '2552', '2553', '2554', '2555']
concat_data = {}
for i in range(len(years)):
    concat_data[year_list[i]] = pd.concat(years[i])

In [20]:
num_row_months = []
for yr in years:
    num_row = []
    for m in yr:
        num_row.append(len(m))
    num_row_months.append(num_row)

In [21]:
import datetime

fig = plt.figure(figsize=(8,6))
xticks = []
for i in range(len(num_row_months)):
    plt.plot(range(1,13), num_row_months[i], label=year_list[i], marker='o')

for i in range(1,13):
    month = datetime.date(1900, i, 1).strftime('%B')
    xticks.append(month)
    
plt.legend(loc='upper left')
plt.title('Number of Individuals Per Months', size=16)
plt.xticks(range(1,13), xticks, rotation=70, size=10)
plt.savefig('num-per-month.png')



In [22]:
num_per_year = []
for yr in year_list:
    df = concat_data[yr]
    num_per_year.append(len(df))

In [23]:
fig = plt.figure(figsize=(8,6))
plt.bar(range(len(num_per_year)), num_per_year, color='grey')
plt.xticks(np.arange(len(num_per_year))+0.5, year_list, size=16)
plt.title('Number of Individuals Per Year', size=16)
plt.savefig('num-per-year.png')



In [24]:
from collections import Counter
from __future__ import unicode_literals

In [25]:
locations = []
for y, months in enumerate(years):
    for m, df in enumerate(months):
        for loc in df['Location']:
            try:
                locations.append(loc.encode('utf-8'))
                #if 'ชุมชน' in loc.encode('utf-8'):
                #print y, m, '-'*45
            except AttributeError, err:
                pass
                #print err, e, type(e)
locations = Counter(locations)

In [26]:
for e in years[0][0]['Location'].head():
    print e.encode('utf-8')


โรงเรียนนวมินทราชินูทิศ บดินทรเดชา
โรงเรียนนวมินทราชินูทิศ บดินทรเดชา
โรงเรียนนวมินทราชินูทิศ บดินทรเดชา
โรงเรียนนวมินทราชินูทิศ บดินทรเดชา
โรงเรียนนวมินทราชินูทิศ บดินทรเดชา

In [32]:
n=20
sorted_locations = sorted(locations, key=lambda x: locations[x], reverse=True)
#fig = plt.figure(figsize=(8,6))
#plt.title('Top Institutions by The Number of Individuals', size=15)
#plt.bar(range(len(sorted_locations[:n])),
#        [locations[loc] for loc in sorted_locations[:10]],
#        color='grey')

#plt.xticks(np.arange(n)+0.5, range(n), size=16)
#plt.savefig('top-institutions.png')
for n, loc in enumerate(sorted_locations[:10]):
    print n, loc, locations[loc]


0 มหาวิทยาลัยรามคำแหง 8465
1 มหาวิทยาลัยเทคโนโลยีพระจอมเกล้าธนบุรี 7688
2 องค์การเภสัชกรรม 4656
3 สำนักพระราชวัง 4487
4 สำนักงานสลากกินแบ่งรัฐบาล 3796
5 กรมสรรพากร 3375
6 สถาบันเทคโนโลยีพระจอมเกล้าเจ้าคุณทหารลาดกระบัง 2949
7 กรมศุลกากร 2837
8 กรมสรรพสามิต 2204
9 บริษัท อีเทอนัลเรซิ่น จำกัด 2194

In [28]:
from collections import defaultdict
loc_by_year = defaultdict(set)  # locations by year
for y, months in enumerate(years):
    for m, df in enumerate(months):
        for loc in df['Location']:
            try:
                loc_by_year[loc.encode('utf-8')].add(year_list[y])
            except AttributeError, err:
                pass

In [29]:
sorted_loc_by_year = sorted(loc_by_year, key=lambda x: len(loc_by_year[x]), reverse=True)
num_per_loc = []
for n, k in enumerate(sorted_loc_by_year):
    num_per_loc.append(len(loc_by_year[k]))
num_per_loc = Counter(num_per_loc)
total_loc = sum([num_per_loc[i] for i in num_per_loc])

In [30]:
fig = plt.figure(figsize=(8,6))
plt.bar(range(1,6), [num_per_loc[i]/float(total_loc)*100.0 for i in num_per_loc], color='grey')
plt.xticks(np.arange(1,6)+0.4, range(1,6), size=16)
plt.ylabel('Percentage of Institutions', size=15)
plt.xlabel('Number of Years', size=15)
plt.title('Number of Institutions Categorized\nby the Number of Years', size=16)
plt.savefig('num-loc-years.png')



In [40]:
for k in loc_by_year:
    if len(loc_by_year[k]) >= 4:
        print k, 'year:', len(loc_by_year[k]), 'number of cases:', locations[k]


โรงเรียนมัธยมวัดดุสิตาราม year: 4 number of cases: 194
โรงเรียนเตรียมอุดมศึกษาพัฒนาการ year: 4 number of cases: 355
คณะวิทยาศาสตร์ มหาวิทยาลัยมหิดล year: 5 number of cases: 1427
โรงเรียนสายปัญญารังสิต year: 4 number of cases: 259
สถาบันวิจัยภาษาและวัฒนธรรมเอเซีย  ม.หิดล year: 5 number of cases: 309
สถาบันวิจัยประชากรและสังคมศาสตร์ ม.มหิดล year: 5 number of cases: 385
สถาบันชีววิทยาศาสตร์โมเลกุล year: 5 number of cases: 431
สำนักงานสลากกินแบ่งรัฐบาล year: 5 number of cases: 3796
โรงเรียนนวมินทราชินูทิศ บดินทรเดชา year: 5 number of cases: 331
โรงเรียนวัดโพธิ์ (ราษฎร์ผดุงผล) ตลิ่งชัน year: 5 number of cases: 421
คณะสังคมศาสตร์และมนุษยศาสตร์ ม.มหิดล year: 5 number of cases: 273
โรงเรียนสตรีวัดระฆัง year: 4 number of cases: 264
คณะเภสัชศาสตร์ มหาวิทยาลัยมหิดล year: 5 number of cases: 545
คณะสัตวแพทยศาสตร์ มหาวิทยาลัยมหิดล year: 4 number of cases: 869
โรงเรียนศรีอยุธยาในพระบรมราชูปถัมภ์ year: 4 number of cases: 368
โรงเรียนโพธิสารพิทยากร year: 4 number of cases: 426
สถาบันโภชนาการ มหาวิทยาลัยมหิดล year: 5 number of cases: 656
โรงเรียนพรตพิทยพยัต year: 4 number of cases: 257
สถาบันเทคโนโลยีพระจอมเกล้าเจ้าคุณทหารลาดกระบัง year: 5 number of cases: 2949
คณะพยาบาลศาสตร์ มหาวิทยาลัยมหิดล year: 4 number of cases: 1477
โรงเรียนสตรีสมุทรปราการ year: 5 number of cases: 393
มหาวิทยาลัยเทคโนโลยีราชมงคลรัตนโกสินทร์ วิทยาเขตบพิตรพิมุขจักรวรรดิ year: 5 number of cases: 291
มหาวิทยาลัยศิลปากร year: 5 number of cases: 1643
บริษัท อีเทอนัลเรซิ่น จำกัด year: 5 number of cases: 2194
มหาวิทยาลัยเทคโนโลยีราชมงคลพระนคร year: 5 number of cases: 407
เรือนจำพิเศษธนบุรี year: 5 number of cases: 572
คณะเทคนิคการแพทย์ มหาวิทยาลัยมหิดล year: 5 number of cases: 1019
ศาลแขวงดุสิต year: 5 number of cases: 283
โรงเรียนสวนกุหลาบวิทยาลัย year: 4 number of cases: 520
โรงเรียนสาธิตแห่งมหาวิทยาลัยเกษตรศาสตร์ year: 5 number of cases: 904
โรงเรียนทวีธาภิเศก year: 5 number of cases: 349
โรงเรียนวัดสุทธิวราราม year: 4 number of cases: 327
วิทยาลัยดุริยางคศิลป์ มหาวิทยาลัยมหิดล year: 5 number of cases: 619
สถาบันพัฒนาสุขภาพอาเซียน ม.มหิดล year: 4 number of cases: 263
CAPITAL ADVISARY SERVICES (THAILAND) LTD. year: 5 number of cases: 264
บริษัทกิบไทย (ประเทศไทย) จำกัด year: 4 number of cases: 405
กรมการค้าภายใน year: 5 number of cases: 1509
โรงเรียนมัธยมวัดเบญจมบพิตร year: 4 number of cases: 145
สมาคมผู้เกษียณอายุราชการสำนักงานสลากกินแบ่งรัฐบาล year: 5 number of cases: 278
วิทยาลัยราชสุดา มหาวิทยาลัยมหิดล year: 4 number of cases: 215
โรงเรียนปทุมคงคา year: 5 number of cases: 351
วิทยาลัยวิทยาศาสตร์และเทคโนโลยีการกีฬา year: 5 number of cases: 350
โรงเรียนสวนอนันต์ year: 5 number of cases: 324
สำนักงานอธิการบดี มหาวิทยาลัยมหิดล year: 5 number of cases: 1774
หอสมุดและคลังความรู้มหาวิทยาลัยมหิดล year: 5 number of cases: 326
โรงเรียนวัดบวรนิเวศ year: 5 number of cases: 281
โรงเรียนสตรีนนทบุรี year: 4 number of cases: 272
โรงเรียนวัดประยุรวงศาวาส year: 5 number of cases: 153
บริษัท วิทยาศรม จำกัด year: 5 number of cases: 459
กรมสรรพสามิต year: 5 number of cases: 2204
คณะสิ่งแวดล้อมและทรัพยากรศาสตร์ มหาวิทยาลัยมหิดล year: 5 number of cases: 351
ศูนย์สัตว์ทดลองแห่งชาติ มหาวิทยาลัยมหิดล year: 4 number of cases: 471
โรงเรียนบดินทรเดชา (สิงห์ สิงหเสนี) year: 5 number of cases: 374
โรงเรียนสตรีวิทยา ราชดำเนิน year: 4 number of cases: 604
สำนักงาน บริษัท สยามเฆมี จำกัด year: 5 number of cases: 265
มหาวิทยาลัยราชภัฏจันทรเกษม year: 5 number of cases: 605
มหาวิทยาลัยราชภัฏวไลยอลงกรณ์ ในพระบรมราชูปถัมภ์ year: 4 number of cases: 678
วิทยาลัยอาชีวศึกษาธนบุรี year: 5 number of cases: 366
บัณฑิตวิทยาลัย มหาวิทยาลัยมหิดล year: 5 number of cases: 455
องค์การคลังสินค้า year: 5 number of cases: 1487
โรงเรียนสามเสนวิทยาลัย year: 5 number of cases: 472
มหาวิทยาลัยเทคโนโลยีพระจอมเกล้าธนบุรี year: 5 number of cases: 7688
สำนักงานปฏิรูปที่ดินเพื่อการเกษตรกรรม year: 5 number of cases: 866
บริษัท อาคเนย์อุตสาหกรรมบรรจุภัณฑ์ จำกัด year: 5 number of cases: 1099
บริษัท สยามเฆมี จำกัด (โรงงาน) year: 5 number of cases: 1397
โรงเรียนศึกษานารี year: 5 number of cases: 459
สำนักงานเลขาธิการสภาการศึกษา year: 5 number of cases: 724
Mahidol University International College (พนักงาน) year: 4 number of cases: 691
โรงเรียนสตรีวัดอัปสรสวรรค์ year: 5 number of cases: 471
โรงเรียนวิสุทธิกษัตรี year: 4 number of cases: 325
ชุมนุมสหกรณ์ออมทรัพย์แห่งประเทศไทย จำกัด year: 5 number of cases: 362
โรงเรียนโยธินบูรณะ year: 5 number of cases: 341
สถาบันส่งเสริมการสอนวิทยาศาสตร์และเทคโนโลยี year: 5 number of cases: 1114
โรงเรียนเบญจมราชาลัย year: 4 number of cases: 287
คณะศิลปศาสตร์ มหาวิทยาลัยมหิดล year: 5 number of cases: 329
กรมราชองครักษ์ year: 4 number of cases: 1455
มหาวิทยาลัยเทคโนโลยีราชมงคลรัตนโกสินทร์ วิทยาเขตเพาะช่าง year: 5 number of cases: 324
คณะวิศวกรรมศาสตร์ มหาวิทยาลัยมหิดล year: 4 number of cases: 540
มหาวิทยาลัยรามคำแหง year: 5 number of cases: 8465

In [31]:
for yr in concat_data:
    concat_data[yr].to_excel(yr + '.xls')


---------------------------------------------------------------------------
KeyboardInterrupt                         Traceback (most recent call last)
<ipython-input-31-7e0c375f3f83> in <module>()
      1 for yr in concat_data:
----> 2     concat_data[yr].to_excel(yr + '.xls')

//anaconda/envs/comm-health/lib/python2.7/site-packages/pandas/util/decorators.pyc in wrapper(*args, **kwargs)
     86                 else:
     87                     kwargs[new_arg_name] = new_arg_value
---> 88             return func(*args, **kwargs)
     89         return wrapper
     90     return _deprecate_kwarg

//anaconda/envs/comm-health/lib/python2.7/site-packages/pandas/core/frame.pyc in to_excel(self, excel_writer, sheet_name, na_rep, float_format, columns, header, index, index_label, startrow, startcol, engine, merge_cells, encoding, inf_rep)
   1258         formatted_cells = formatter.get_formatted_cells()
   1259         excel_writer.write_cells(formatted_cells, sheet_name,
-> 1260                                  startrow=startrow, startcol=startcol)
   1261         if need_save:
   1262             excel_writer.save()

//anaconda/envs/comm-health/lib/python2.7/site-packages/pandas/io/excel.pyc in write_cells(self, cells, sheet_name, startrow, startcol)
   1115         style_dict = {}
   1116 
-> 1117         for cell in cells:
   1118             val = _conv_value(cell.val)
   1119 

//anaconda/envs/comm-health/lib/python2.7/site-packages/pandas/core/format.pyc in get_formatted_cells(self)
   1826         for cell in itertools.chain(self._format_header(),
   1827                                     self._format_body()):
-> 1828             cell.val = self._format_value(cell.val)
   1829             yield cell
   1830 

//anaconda/envs/comm-health/lib/python2.7/site-packages/pandas/core/format.pyc in _format_value(self, val)
   1604             if np.isposinf(val):
   1605                 val = self.inf_rep
-> 1606             elif np.isneginf(val):
   1607                 val = '-%s' % self.inf_rep
   1608             elif self.float_format is not None:

//anaconda/envs/comm-health/lib/python2.7/site-packages/numpy/lib/ufunclike.pyc in isneginf(x, y)
    172     """
    173     if y is None:
--> 174         x = nx.asarray(x)
    175         y = nx.empty(x.shape, dtype=nx.bool_)
    176     nx.logical_and(nx.isinf(x), nx.signbit(x), y)

//anaconda/envs/comm-health/lib/python2.7/site-packages/numpy/core/numeric.pyc in asarray(a, dtype, order)
    460 
    461     """
--> 462     return array(a, dtype, copy=False, order=order)
    463 
    464 def asanyarray(a, dtype=None, order=None):

KeyboardInterrupt: 

In [ ]:
pwd

In [ ]: