|
| 1 | + |
| 2 | +import numpy as np |
| 3 | +import pandas as pd |
| 4 | +import os # For saving output to path |
| 5 | +import sys |
| 6 | +""" |
| 7 | +
|
| 8 | +Python Version 3.8.12 | packaged by conda-forge | (default, Oct 12 2021, 21:22:46) [MSC v.1916 64 bit (AMD64)] |
| 9 | +numpy version: 1.22.0 |
| 10 | +pandas version: 1.3.5 |
| 11 | +
|
| 12 | +""" |
| 13 | + |
| 14 | +# open, read, and execute python program with reusable commands |
| 15 | +from pyincore_data_addons.SourceData.api_census_gov.tidy_censusapi \ |
| 16 | + import tidy_censusapi |
| 17 | + |
| 18 | +from pyincore_data_addons.ICD01a_obtain_sourcedata import obtain_sourcedata |
| 19 | +from pyincore_data_addons.ICD02a_clean import clean_comm_data_intrsctn |
| 20 | +from pyincore_data_addons.ICD03a_results_table import pop_results_table as viz |
| 21 | +from pyincore_data_addons.SourceData.nces_ed_gov.nces_01a_obtain \ |
| 22 | + import nces_obtain_ccd0910 |
| 23 | +from pyincore_data_addons.SourceData.nces_ed_gov.nces_02a_tidy \ |
| 24 | + import tidy_nces |
| 25 | +from pyincore_data_addons.ICD00b_directory_design import directory_design |
| 26 | +from pyincore_data_addons.SourceData.api_census_gov.hui_add_categorical_char \ |
| 27 | + import add_new_char_by_random_merge_2dfs |
| 28 | + |
| 29 | + |
| 30 | +def intersect_prechui_nces(communities, outputfolder, seed, basevintage): |
| 31 | + """ |
| 32 | + Example Datastructure inputs: |
| 33 | + communities = {'Lumberton_NC' : { |
| 34 | + 'community_name' : 'Lumberton, NC', |
| 35 | + 'counties' : { |
| 36 | + 1 : {'FIPS Code' : '37155', 'Name' : 'Robeson County, NC'}}}, |
| 37 | + } |
| 38 | +
|
| 39 | +
|
| 40 | + seed = 9876 |
| 41 | + basevintage = '2010' |
| 42 | + outputfolder = "ICD_workflow_2022-01-19" |
| 43 | + """ |
| 44 | + version_text = "v0-2-0" |
| 45 | + |
| 46 | + # Setup directory design |
| 47 | + for community in communities.keys(): |
| 48 | + print("Intersect Community Data for:",\ |
| 49 | + communities[community]['community_name']) |
| 50 | + for county in communities[community]['counties'].keys(): |
| 51 | + state_county = communities[community]['counties'][county]['FIPS Code'] |
| 52 | + state_county_name = communities[community]['counties'][county]['Name'] |
| 53 | + print(state_county_name,': county FIPS Code',state_county) |
| 54 | + |
| 55 | + outputfolders = directory_design(state_county_name = state_county_name, |
| 56 | + outputfolder = outputfolder) |
| 57 | + |
| 58 | + # Read in Housing Unit Inventory and Person Records |
| 59 | + obtain_dfs = obtain_sourcedata(communities=communities, |
| 60 | + outputfolder = outputfolder, |
| 61 | + seed = seed, |
| 62 | + basevintage = basevintage) |
| 63 | + |
| 64 | + hui_df, prechui_df = obtain_dfs.read_hui_prechui_data_csv_to_df() |
| 65 | + |
| 66 | + # Read in Place Names |
| 67 | + place_df = obtain_dfs.block_place_csv_to_df() |
| 68 | + |
| 69 | + # Merge Person Records with place names |
| 70 | + ## Add Place to Person Record Data |
| 71 | + # Place (city) is a helpful variable for |
| 72 | + # exploring results of person records |
| 73 | + keep_vars = ['Block2010','PLCGEOID10','PLCNAME10','PUMGEOID10','rppnt4269'] |
| 74 | + prechui_df = pd.merge(left = prechui_df, |
| 75 | + right = place_df[keep_vars], |
| 76 | + on = 'Block2010') |
| 77 | + # fill in missing placenames |
| 78 | + prechui_df.loc[prechui_df['PLCNAME10'].isnull(),'PLCNAME10'] = 'Unincorporated' |
| 79 | + """ Explore data |
| 80 | + hui_df.head() |
| 81 | + prechui_df.head() |
| 82 | + prechui_df.describe().T |
| 83 | + """ |
| 84 | + |
| 85 | + # Add Grade Level |
| 86 | + clean_df = clean_comm_data_intrsctn(seed=seed, |
| 87 | + randage_var = 'randagePCT12', |
| 88 | + kgentage = 5, # Kindergarten entrance age |
| 89 | + kgageby = '08-31', # Kindergarten age by date |
| 90 | + schoolyear = '2009', |
| 91 | + census_day = '2010-04-01') |
| 92 | + gradelevel_df = clean_df.add_gradelevel_to_prechui( |
| 93 | + input_df = prechui_df) |
| 94 | + |
| 95 | + # Add race by 5 categories to match NCES |
| 96 | + gradelevel_df = clean_df.add_racecat5(gradelevel_df) |
| 97 | + |
| 98 | + # Obtain School Attendance Boundary Data |
| 99 | + sabs_df = obtain_dfs.read_nces_sab_csv_to_df() |
| 100 | + |
| 101 | + # Merge Person Records with SABS |
| 102 | + sabs_gradelevel_df = pd.merge(left = gradelevel_df, |
| 103 | + right = sabs_df, |
| 104 | + on = 'Block2010') |
| 105 | + |
| 106 | + # Manual fix for Robeson County SABS |
| 107 | + sabs_gradelevel_df = clean_df.manual_fix_RobesonCounty(sabs_gradelevel_df) |
| 108 | + |
| 109 | + # Identify Community of Interest |
| 110 | + # For Lumberton the community of interest is Lumberton Junior High SABS |
| 111 | + sabs_gradelevel_df['CommunityFocus'] = 'Outside Community' |
| 112 | + sabs_gradelevel_df.loc[sabs_gradelevel_df['ncessch_2']== '370393002236' ,\ |
| 113 | + 'CommunityFocus'] = 'Inside Community' |
| 114 | + |
| 115 | + |
| 116 | + ## Read in NCES Student Data |
| 117 | + srec_df = tidy_nces(outputfolder = outputfolders['TidySourceData']) |
| 118 | + |
| 119 | + #Random Merge with Person Records |
| 120 | + """ |
| 121 | + Check data types before merge |
| 122 | + geo_levels = ['ncessch_1','ncessch_2','ncessch_3','ncessch_5','ncessch_6'] |
| 123 | + common_group_vars = ['gradelevel1','gradelevel2','sex','racecat5'] |
| 124 | + sabs_gradelevel_df[geo_levels+common_group_vars].dtypes |
| 125 | + srec_df[geo_levels+common_group_vars].dtypes |
| 126 | + """ |
| 127 | + print("\n***************************************") |
| 128 | + print(" Random merge between Person Records and Student records.") |
| 129 | + print("***************************************\n") |
| 130 | + |
| 131 | + # intersect by each grade level over school options |
| 132 | + prechui_intersect_srec_df = sabs_gradelevel_df.copy() |
| 133 | + for gradelevel in ['gradelevel1','gradelevel2','gradelevel3']: |
| 134 | + prechui_srec = add_new_char_by_random_merge_2dfs( |
| 135 | + dfs = {'primary' : {'data': prechui_intersect_srec_df, |
| 136 | + 'primarykey' : 'precid', |
| 137 | + 'geolevel' : 'School Attendance Boundary', |
| 138 | + 'geovintage' :'2010', |
| 139 | + 'notes' : 'Person records with race, hispan, gradelevel, schoolid, sex.'}, |
| 140 | + 'secondary' : {'data': srec_df, |
| 141 | + 'primarykey' : 'srecid', # primary key needs to be different from new char |
| 142 | + 'geolevel' : 'School Attendance Boundary', |
| 143 | + 'geovintage' :'2010', |
| 144 | + 'notes' : 'Student Record Data.'}}, |
| 145 | + seed = seed, #self.seed, |
| 146 | + common_group_vars = [gradelevel,'sex','racecat5'], |
| 147 | + new_char = 'NCESSCH', |
| 148 | + extra_vars = ['SCHNAM09','gradelevel','LATCOD09','LONCOD09'], |
| 149 | + geolevel = "Block", |
| 150 | + geovintage = "2010", |
| 151 | + by_groups = {'NA' : {'by_variables' : []}}, |
| 152 | + fillna_value= '-999', |
| 153 | + state_county = state_county, #self.state_county, |
| 154 | + outputfile = "prec_srec_schoolid", |
| 155 | + outputfolder = outputfolders['RandomMerge']) #self.outputfolders['RandomMerge']) |
| 156 | + |
| 157 | + # Set up round options |
| 158 | + rounds = {'options': { |
| 159 | + 'studentall' : {'notes' : 'Attempt to merge students on all common group vars.', |
| 160 | + 'common_group_vars' : |
| 161 | + prechui_srec.common_group_vars, |
| 162 | + 'by_groups' : |
| 163 | + prechui_srec.by_groups}, |
| 164 | + 'studentnorace' : {'notes' : 'Attempt to merge students without racecat5.', |
| 165 | + 'common_group_vars' : |
| 166 | + [gradelevel,'sex'], |
| 167 | + 'by_groups' : |
| 168 | + prechui_srec.by_groups}, |
| 169 | + 'studentnosex' : {'notes' : 'Attempt to merge students without sex.', |
| 170 | + 'common_group_vars' : |
| 171 | + [gradelevel], |
| 172 | + 'by_groups' : |
| 173 | + prechui_srec.by_groups}, |
| 174 | + }, |
| 175 | + 'geo_levels' : ['ncessch_1','ncessch_2','ncessch_3','ncessch_5','ncessch_6'] |
| 176 | + } |
| 177 | + |
| 178 | + # Update person record school record file for next merge |
| 179 | + prechui_srec_df = prechui_srec.run_random_merge_2dfs(rounds) |
| 180 | + prechui_intersect_srec_df = prechui_srec_df['primary'] |
| 181 | + srec_df = prechui_srec_df['secondary'] |
| 182 | + |
| 183 | + """ Explore data |
| 184 | + prechui_srec_df['primary'].head() |
| 185 | + table_df = prechui_srec_df['primary'] |
| 186 | + results_df = pd.pivot_table(table_df, |
| 187 | + values = ['precid'], |
| 188 | + index=['NCESSCH','SCHNAM09'], |
| 189 | + aggfunc={'precid':'count'}, |
| 190 | + margins=True, margins_name = 'Total') |
| 191 | + |
| 192 | + county_condition = (ccd_df['CONUM09'] == '37155') |
| 193 | + keep_vars = ['NCESSCH','SCHNAM09','MEMBER09','CONUM09'] |
| 194 | + ccd_county_select = ccd_df[keep_vars].loc[county_condition] |
| 195 | +
|
| 196 | + # Merge CCD data with person record results |
| 197 | + check_results = pd.merge(left = results_df, |
| 198 | + right = ccd_county_select, |
| 199 | + on = ['NCESSCH','SCHNAM09']) |
| 200 | + |
| 201 | + check_results['check_diff'] = check_results['MEMBER09'] - check_results['precid'] |
| 202 | + check_results['prct_check_diff'] = check_results['check_diff'] / check_results['MEMBER09'] |
| 203 | + check_results['check_diff'].describe() |
| 204 | + np.array(check_results['precid']).sum() |
| 205 | + np.array(check_results['MEMBER09']).sum() |
| 206 | + np.array(check_results['check_diff']).sum() |
| 207 | + check_results['prct_check_diff'].describe() |
| 208 | + check_results.loc[check_results['prct_check_diff'] > .05] |
| 209 | + gradelevel_condition = (prechui_srec_df['primary']['gradelevel1'] != 'NA') |
| 210 | + school_missing = (prechui_srec_df['primary']['NCESSCH'] == '-999') |
| 211 | + conditions = gradelevel_condition & school_missing |
| 212 | + table_df = prechui_srec_df['primary'].loc[conditions] |
| 213 | + pd.pivot_table(table_df, |
| 214 | + values = ['precid'], |
| 215 | + index=['gradelevel1'], |
| 216 | + columns = 'race', |
| 217 | + aggfunc={'precid':'count'}, |
| 218 | + margins=True, margins_name = 'Total') |
| 219 | +
|
| 220 | + table_df = prechui_srec_df['secondary'] |
| 221 | + pd.pivot_table(table_df, |
| 222 | + values = ['srecid'], |
| 223 | + index=['NCESSCH_flagsetrm'], |
| 224 | + columns = 'LEVEL09', |
| 225 | + aggfunc={'srecid':'count'}, |
| 226 | + margins=True, margins_name = 'Total') |
| 227 | + table_df = prechui_srec_df['secondary'] |
| 228 | + pd.pivot_table(table_df, |
| 229 | + values = ['srecid'], |
| 230 | + index=['gradelevel'], |
| 231 | + columns = 'NCESSCH_flagsetrm', |
| 232 | + aggfunc={'srecid':'count'}, |
| 233 | + margins=True, margins_name = 'Total') |
| 234 | + table_df = prechui_srec_df['secondary'] |
| 235 | + pd.pivot_table(table_df, |
| 236 | + values = ['srecid'], |
| 237 | + index=['racecat5'], |
| 238 | + columns = 'NCESSCH_flagsetrm', |
| 239 | + aggfunc={'srecid':'count'}, |
| 240 | + margins=True, margins_name = 'Total') |
| 241 | + table_df = prechui_srec_df['primary'] |
| 242 | + pd.pivot_table(table_df, |
| 243 | + values = ['precid'], |
| 244 | + index=['racecat5','gradelevel'], |
| 245 | + columns = 'NCESSCH_flagsetrm', |
| 246 | + aggfunc={'precid':'count'}, |
| 247 | + margins=True, margins_name = 'Total') |
| 248 | + """ |
| 249 | + |
| 250 | + """ Explore data |
| 251 | + sabs_gradelevel_df.head(1).T |
| 252 | + pd.pivot_table(sabs_gradelevel_df, |
| 253 | + values = ['precid'], |
| 254 | + index=['high_schnm','ncessch_3'], |
| 255 | + aggfunc={'precid':'count'}, |
| 256 | + margins=True, margins_name = 'Total') |
| 257 | +
|
| 258 | + pd.pivot_table(sabs_gradelevel_df, |
| 259 | + values = ['precid'], |
| 260 | + index=['mid_schnm','ncessch_2'], |
| 261 | + aggfunc={'precid':'count'}, |
| 262 | + margins=True, margins_name = 'Total') |
| 263 | +
|
| 264 | + pd.pivot_table(sabs_gradelevel_df, |
| 265 | + values = ['precid'], |
| 266 | + index=['primary_schnm','ncessch_1'], |
| 267 | + aggfunc={'precid':'count'}, |
| 268 | + margins=True, margins_name = 'Total') |
| 269 | +
|
| 270 | + pd.pivot_table(sabs_gradelevel_df.loc[sabs_gradelevel_df['ncessch_2'].isnull()], |
| 271 | + values = ['precid'], |
| 272 | + index=['high_schnm','ncessch_3','primary_schnm','ncessch_1'], |
| 273 | + aggfunc={'precid':'count'}, |
| 274 | + margins=True, margins_name = 'Total') |
| 275 | + |
| 276 | + from pyincore_data_addons.ICD03a_results_table import pop_results_table as viz |
| 277 | + viz.pop_results_table(sabs_gradelevel_df, |
| 278 | + who = "Total Population by Persons", |
| 279 | + what = "by Race, Ethnicity", |
| 280 | + where = "Robeson County, NC", |
| 281 | + when = "2010", |
| 282 | + row_index = 'Race Ethnicity', |
| 283 | + col_index = 'Family Type', |
| 284 | + row_percent = "1 Family Household") |
| 285 | + """ |
| 286 | + print("\n***************************************") |
| 287 | + print(" Try to polish final prechui srec data.") |
| 288 | + print("***************************************\n") |
| 289 | + |
| 290 | + # Sort data by huid and person counter |
| 291 | + prechui_srec_df['primary'] = \ |
| 292 | + prechui_srec_df['primary'].sort_values(by = ['huid','pernum']) |
| 293 | + # move huid to second column |
| 294 | + # Create column list to move primarykey to first column |
| 295 | + primary_key_names = ['precid','huid','pernum','Block2010str'] |
| 296 | + columnlist = [col for col in prechui_srec_df['primary'] if col not in primary_key_names] |
| 297 | + new_columnlist = primary_key_names + columnlist |
| 298 | + prechui_srec_df['primary'] = prechui_srec_df['primary'][new_columnlist] |
| 299 | + |
| 300 | + # Clean geometry column and add lat lon |
| 301 | + prechui_srec_df['primary'] = clean_df.clean_geometry(prechui_srec_df['primary'], |
| 302 | + projection = "epsg:4269", |
| 303 | + reproject = "epsg:4326", |
| 304 | + geometryvar = 'rppnt4269', |
| 305 | + latlontype = 'hcb') |
| 306 | + # drop extra columns |
| 307 | + prec_srec_df = clean_df.drop_extra_columns(prechui_srec_df['primary']) |
| 308 | + prec_srec_df = clean_df.clean_gradelevel(prec_srec_df) |
| 309 | + |
| 310 | + |
| 311 | + print("\n***************************************") |
| 312 | + print(" Save cleaned data file.") |
| 313 | + print("***************************************\n") |
| 314 | + |
| 315 | + output_filename = f'prechui_srec_{version_text}_{state_county}_{basevintage}_rs{seed}' |
| 316 | + csv_filepath = outputfolders['top']+"/"+output_filename+'.csv' |
| 317 | + savefile = sys.path[0]+"/"+csv_filepath |
| 318 | + prec_srec_df.to_csv(savefile, index=False) |
| 319 | + print("File saved:",savefile) |
| 320 | + |
| 321 | + return prechui_srec_df |
| 322 | + |
| 323 | + |
0 commit comments