def find_current_employment_type(mgras, mgra): ''' mgra: read-only row in the original dataframe returns: the product type labels corresponding to the type with the most units already developed ''' industrial_labels = ProductTypeLabels(INDUSTRIAL) industrial_spaces = mgra[industrial_labels.total_units].item() commercial_labels = ProductTypeLabels(COMMERCIAL) commercial_spaces = mgra[commercial_labels.total_units].item() office_labels = ProductTypeLabels(OFFICE) office_spaces = mgra[office_labels.total_units].item() if industrial_spaces == 0 and \ commercial_spaces == 0 and office_spaces == 0: # if there are no units, check the LUZ for units return find_largest_luz_employment_type(mgras, mgra[mgra_labels.LUZ].item()) return pick_labels_with_highest_value( [industrial_labels, commercial_labels, office_labels], [industrial_spaces, commercial_spaces, office_spaces])
def setUp(self): # self.test_mgras = pandas.read_csv(parameters['input_filename']) self.test_mgras = pandas.read_csv('test_data/random_MGRA.csv') self.product_type_labels = ProductTypeLabels('single_family') self.mgra_label = "MGRA" self.single_family_labels = self.product_type_labels self.multi_family_labels = ProductTypeLabels('multi_family') ''' mgra 1: 12 units, 4 new, 3 old, 5 normal mgra 2: 100 units, 2 new, 4 old, 94 normal mgra 3: 56 units, 5 new, 10 old, 41 normal mgra 4: 350 units, 35 new, 175 old, 140 normal ''' self.housing_age_frame = pandas.DataFrame({ self.mgra_label: [1, 2], self.single_family_labels.proportion_new: [0.333333, 0.02], self.single_family_labels.proportion_old: [0.25, 0.04], self.single_family_labels.total_units: [12, 100], self.multi_family_labels.proportion_new: [0.0892, 0.1], self.multi_family_labels.proportion_old: [0.1785, 0.5], self.multi_family_labels.total_units: [56, 350], access.mgra_labels.HOUSING_UNITS: [68, 450] }) self.vacant_labels = [ 'vac_comm', 'vac_indus', 'vac_office', 'vac_mf', 'vac_sf' ]
def add_to_mgra(mgras, site): ''' mgras: the dataframe to update. site: expects a dataframe with one entry, including columns for MGRAID and the number of units to add ''' mgra_id = site.MGRA.item() single_family_units = site.sfu.item() multi_family_units = site.mfu.item() employment_units = site.civEmp.item() if single_family_units > 0: # add single family units labels = ProductTypeLabels(SINGLE_FAMILY) update_mgra(mgras, mgra_id, single_family_units, labels) reduce_demand(labels.product_type, single_family_units) if multi_family_units > 0: # add multifamily units labels = ProductTypeLabels(MULTI_FAMILY) update_mgra(mgras, mgra_id, multi_family_units, labels) reduce_demand(labels.product_type, multi_family_units) if employment_units > 0: # add employment; determine which type to add mgra = mgras.loc[mgras[mgra_labels.MGRA] == mgra_id] labels = find_current_employment_type(mgras, mgra) update_mgra(mgras, mgra_id, employment_units, labels) reduce_demand(labels.product_type, employment_units) return
def setUp(self): self.expected_file_1 = 'data/SRF_Input_Base_V4.1.csv' self.expected_file_2 = 'data/output/scheduled_development_added.csv' self.industrial_labels = ProductTypeLabels("industrial") self.commercial_labels = ProductTypeLabels("commercial") self.office_labels = ProductTypeLabels("office") return
def find_largest_luz_employment_type(mgras, luz_id): industrial_labels = ProductTypeLabels(INDUSTRIAL) commercial_labels = ProductTypeLabels(COMMERCIAL) office_labels = ProductTypeLabels(OFFICE) industrial_spaces = total_for_luz(mgras, luz_id, industrial_labels.total_units) commercial_spaces = total_for_luz(mgras, luz_id, commercial_labels.total_units) office_spaces = total_for_luz(mgras, luz_id, office_labels.total_units) return pick_labels_with_highest_value( [industrial_labels, commercial_labels, office_labels], [industrial_spaces, commercial_spaces, office_spaces])
def test_non_residential_capacity_limiting(self): commercial_labels = ProductTypeLabels(product_type='commercial') # mgra 1 should be filtered out, 2 should find 50 available units, # reduced from 100 by the capacity value. 3's available units should # not be reduced capacity_test_frame = pandas.DataFrame({ 'MGRA': [1, 2, 3], "redev_mf_e": [None, None, None], "redev_mh_e": [None, None, None], "redev_sf_e": [None, None, None], "redev_emp1": [None, None, None], "redev_emp_": [None, None, None], "redev_ag_r": [None, None, None], "redev_ag_l": [None, None, None], 'redev_ag_c': [None, None, None], "infill_emp": [None, None, None], commercial_labels.vacant_acres: [10, 10, 10], mgra_labels.VACANT_ACRES: [10, 10, 10], mgra_labels.LAND_COST_PER_ACRE: [200, 200, 200], mgra_labels.CIVILIAN_EMPLOYMENT_CAPACITY: [50, 100, 150], commercial_labels.price: [200, 200, 200], mgra_labels.TOTAL_JOB_SPACES: [50, 50, 50], commercial_labels.total_units: [50, 50, 50], commercial_labels.occupied_units: [50, 50, 50], "units_available": [100, 100, 100] }) output = filter_product_type(capacity_test_frame, commercial_labels) self.assertEqual(50, output.iloc[0, -1]) self.assertEqual(100, output.iloc[1, -1])
def make_profitability_file(): frame_dict = {mgra_labels.MGRA: [i + 1 for i in range(MGRA_COUNT)]} for product_type in product_types(): frame_dict[ ProductTypeLabels(product_type).profitability_adjust ] = [0]*MGRA_COUNT frame = pandas.DataFrame(frame_dict) save_to_file(frame, 'data', 'profitability.csv', force=True)
def add_job_spaces_columns(dataframe): # start column for total job spaces dataframe[mgra_labels.TOTAL_JOB_SPACES] = 0 # create job spaces column for each non-residential type for product_type in non_residential_types: labels = ProductTypeLabels(product_type) dataframe[labels.total_units] = job_spaces_for_product_type( dataframe, product_type) # also add to the total job spaces column dataframe[mgra_labels.TOTAL_JOB_SPACES] += dataframe[ labels.total_units] return dataframe
def fix_capacity(dataframe): ''' capacity values are unfortunately the leftover capacity, not the total capacity. Add together the current units and the leftover capacity to find the total, then replace the previous values ''' dataframe[mgra_labels.HOUSING_CAPACITY] += dataframe[ mgra_labels.HOUSING_UNITS] for product_type in residential_types: labels = ProductTypeLabels(product_type) dataframe[labels.capacity] += dataframe[labels.total_units] return dataframe
def export_luz_data(frame): luz_dict = luz_dict_from_crosswalk() output_dict = {} focus_columns = [ mgra_labels.LUZ, ProductTypeLabels('industrial').square_footage, ProductTypeLabels('commercial').square_footage, ProductTypeLabels('office').square_footage ] focus_frame = frame[focus_columns] # iterating through a pandas frame returns a python namedtuple for row in focus_frame.itertuples(index=False): # for each mgra # use the namedtuple._asdict to access with the labels we are used to. row_dict = row._asdict() square_footages = [row_dict[focus_columns[1]], row_dict[focus_columns[2]], row_dict[focus_columns[3]] ] if sum(square_footages) != 0: luz = row[0] # find matching LUZ for commodity_info in luz_dict[luz]: # check each commodity type commodity_name = commodity_info['commodity'] ratios = commodity_info['ratios'] quantity = calculate_quantity(square_footages, ratios) if quantity != 0: # if there is some commodity space, add it. # differentiate commodities for each luz with a tuple as a # dict key luz_commodity_tuple = (luz, commodity_name) if luz_commodity_tuple not in output_dict: output_dict[luz_commodity_tuple] = create_row( luz, commodity_name, quantity) else: output_dict[ luz_commodity_tuple ]['Quantity'] += quantity output_frame = pandas.DataFrame(output_dict.values()) # output_frame.sort_values( # by=['Commodity', compatible_row_id_label], inplace=True) return output_frame
def job_spaces_for_product_type(dataframe, product_type): # get applicable columns labels = ProductTypeLabels(product_type) average_area_per_job = dataframe[labels.job_area] current_employment = dataframe[labels.occupied_units] total_area = dataframe[labels.square_footage] # find estimate of unoccupied job spaces used_area = average_area_per_job * current_employment vacant_area = total_area - used_area unoccupied_job_spaces = vacant_area / average_area_per_job # if negative, assume that the spaces are all occupied unoccupied_job_spaces[unoccupied_job_spaces < 0] = 0 total_job_spaces = current_employment + \ unoccupied_job_spaces.astype('int32') return total_job_spaces
def setUp(self): self.mgras = pandas.read_csv('test_data/random_MGRA.csv') self.max_vacancy = 0.06 self.product_type_labels = ProductTypeLabels('single_family') self.combined_frame = pandas.DataFrame({ "MGRA": [1, 2, 3, 4, 5, 6, 7], 'vac': [2.0, 0, 0, 0, 0, 0, 0], "vac_sf": [2.0, None, None, None, None, None, None], "redev_mh_s": [None, None, None, None, None, None, 2.0], "redev_ag_s": [None, None, None, None, None, 2.0, None], "redev_emp1": [None, None, None, None, 2.0, None, None], "redev_ag_r": [None, None, None, 2.0, None, None, None], "redev_ag_l": [None, None, 2.0, None, None, None, None], "infill_sf": [None, 2.0, None, None, None, None, None], mgra_labels.LAND_COST_PER_ACRE: [10000, 200, 300, 400, 500, 600, 700], self.product_type_labels.price: [100, 200, 300, 400, 500, 600, 700], self.product_type_labels.capacity: [100, 200, 300, 400, 500, 600, 700], self.product_type_labels.total_units: [50, 100, 200, 300, 400, 500, 600], "hs_sf": [200, 235, 460, 563, 0, 1000, 1000], "hh_sf": [200, 100, 398, 543, 0, 970, 945], "units_available": [100, 100, 29, 0, 218, 300, 200] }) self.vacancy_frame = pandas.DataFrame({ "id": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11], "hs_sf": [200, 235, 460, 563, 49, 125, 0, 145, 58, 1000, 1000], "hh_sf": [200, 100, 398, 543, 49, 125, 0, 129, 39, 970, 945], "units_available": [100, 100, 29, 45, 0, 218, 1230, 0, 200, 300, 200], }) self.profitability_frame = pandas.DataFrame({ "MGRA": [1, 2, 3, 4, 5, 6, 7], "vac_sf": [2.0, None, None, None, None, None, None], "redev_mh_s": [None, None, None, None, None, None, 2.0], "redev_ag_s": [None, None, None, None, None, 2.0, None], "redev_emp1": [None, None, None, None, 2.0, None, None], "redev_ag_r": [None, None, None, 2.0, None, None, None], "redev_ag_l": [None, None, 2.0, None, None, None, None], "infill_sf": [None, 2.0, None, None, None, None, None], mgra_labels.LAND_COST_PER_ACRE: [10000, 200, 300, 400, 500, 600, 700], self.product_type_labels.price: [100, 200, 300, 400, 500, 600, 700] }) return super().setUp()
def test_add_to_columns(self): housing_label = access.mgra_labels.HOUSING_UNITS specific_label = ProductTypeLabels().total_units total_housing_before = self.test_mgras[housing_label].sum() single_family_units_before = \ self.test_mgras[specific_label].sum() mgra_id = self.test_mgras.sample()[access.mgra_labels.MGRA].iloc[0] units = 1 add_to_columns(self.test_mgras, mgra_id, units, [housing_label, specific_label]) self.assertGreater(self.test_mgras[housing_label].sum(), total_housing_before) self.assertGreater(self.test_mgras[specific_label].sum(), single_family_units_before)
def setUp(self): self.candidate = pandas.DataFrame({ "vacancy_cap": [20], "vac_sf": [6.0], "redev_mh_s": [None], "redev_ag_s": [None], "redev_emp1": [None], "redev_ag_r": [None], "redev_ag_l": [None], "infill_sf": [None], }) self.product_type_labels = ProductTypeLabels('single_family') self.short_mgras = pandas.read_csv('test_data/random_MGRA.csv') self.test_mgras = pandas.read_csv('data/SRF_Input_Base_V4.1.csv') return super().setUp()
def select_candidate_for_product_type(self, product_type): # filtered = self.product_type_tables[product_type] filtered = apply_filters(self.candidates, ProductTypeLabels(product_type)) # uncomment to debug candidate filtering # save_to_file(filtered, 'data/output', 'filtered_candidates.csv') if len(filtered) < 1: return None # Sample weights = combine_weights(filtered.profit_margin, filtered.vacancy_cap) # DataFrame.sample replace argument is False by default, so the # selected candidate will not be considered again. logging.debug('{} candidates left for product type {}'.format( len(filtered), product_type)) selected = filtered.sample(n=1, weights=weights) # .sample only removed the candidate from the filtered copy, also # remove it from the original candidates self.candidates.drop([selected.index.array[0]], inplace=True) return selected
def average_jobs_per_unit(filename, product_type): labels = ProductTypeLabels(product_type) jobs = labels.occupied_units units = labels.buildings average_x_per_y(filename, jobs, units, product_type)
def setUp(self): self.test_mgras = pandas.read_csv(parameters['input_filename']) self.product_type_labels = ProductTypeLabels('single_family')
def average_land_per_unit(filename, product_type): labels = ProductTypeLabels(product_type) developed_area = labels.developed_acres units = labels.total_units average_x_per_y(filename, developed_area, units, product_type)
def average_unit_square_footage(filename, product_type): labels = ProductTypeLabels(product_type) total_sqft = labels.square_footage total_units = labels.total_units average_x_per_y(filename, total_sqft, total_units, product_type)