def subsidized_office_developer(feasibility, coffer, acct_settings, year, add_extra_columns_func, buildings, summary): # get the total subsidy for subsidizing office total_subsidy = coffer["vmt_com_acct"].\ total_transactions_by_subacct("regional") # get the office feasibility frame and sort by profit per sqft feasibility = feasibility.to_frame().loc[:, "office"] if "max_profit" not in feasibility.columns: feasibility["max_profit"] = 0 feasibility = feasibility.dropna(subset=["max_profit"]) if "pda" not in feasibility.columns: feasibility["pda"] = np.nan feasibility["pda_id"] = feasibility.pda # filter to receiving zone feasibility = feasibility.\ query(acct_settings["vmt_settings"]["receiving_buildings_filter"]) if "non_residential_sqft" not in feasibility.columns: feasibility["non_residential_sqft"] = 0 feasibility["non_residential_sqft"] = \ feasibility.non_residential_sqft.astype("int") feasibility["max_profit_per_sqft"] = feasibility.max_profit / \ feasibility.non_residential_sqft # sorting by our choice metric as we're going to pick our devs # in order off the top feasibility = feasibility.sort_values(['max_profit_per_sqft']) # make parcel_id available feasibility = feasibility.reset_index() print "%.0f subsidy with %d developments to choose from" % ( total_subsidy, len(feasibility)) devs = [] for dev_id, d in feasibility.iterrows(): # the logic here is that we allow each dev to have a "normal" # profit per square foot and once it does we guarantee that it # gets build - we assume the planning commission for each city # enables this to happen. If a project gets enough profit already # we just allow it to compete on the open market - e.g. in the # non-subsidized office developer NORMAL_PROFIT_PER_SQFT = 70 # assume price is around $700/sqft if d.max_profit_per_sqft >= NORMAL_PROFIT_PER_SQFT: # competes in open market continue else: amt = (NORMAL_PROFIT_PER_SQFT - d.max_profit_per_sqft) * \ d.non_residential_sqft if amt > total_subsidy: # we don't have enough money to buy yet continue metadata = { "description": "Developing subsidized office building", "year": year, "non_residential_sqft": d["non_residential_sqft"], "index": dev_id } coffer["vmt_com_acct"].add_transaction(-1 * amt, subaccount="regional", metadata=metadata) total_subsidy -= amt devs.append(d) if len(devs) == 0: return # record keeping - add extra columns to match building dataframe # add the buidings and demolish old buildings, and add to debug output devs = pd.DataFrame(devs, columns=feasibility.columns) print "Building {:,} subsidized office sqft in {:,} projects".format( devs.non_residential_sqft.sum(), len(devs)) devs["form"] = "office" devs = add_extra_columns_func(devs) add_buildings(buildings, devs) summary.add_parcel_output(devs)
def retail_developer(jobs, buildings, parcels, nodes, feasibility, settings, summary, add_extra_columns_func, net): dev_settings = settings['non_residential_developer'] all_units = dev.compute_units_to_build( len(jobs), buildings.job_spaces.sum(), dev_settings['kwargs']['target_vacancy']) target = all_units * float(dev_settings['type_splits']["Retail"]) # target here is in sqft target *= settings["building_sqft_per_job"]["HS"] feasibility = feasibility.to_frame().loc[:, "retail"] feasibility = feasibility.dropna(subset=["max_profit"]) feasibility["non_residential_sqft"] = \ feasibility.non_residential_sqft.astype("int") feasibility["retail_ratio"] = parcels.retail_ratio feasibility = feasibility.reset_index() # create features f1 = feasibility.retail_ratio / feasibility.retail_ratio.max() f2 = feasibility.max_profit / feasibility.max_profit.max() # combine features in probability function - it's like combining expense # of building the building with the market in the neighborhood p = f1 * 1.5 + f2 p = p.clip(lower=1.0 / len(p) / 10) print "Attempting to build {:,} retail sqft".format(target) # order by weighted random sample feasibility = feasibility.sample(frac=1.0, weights=p) foreign_columns = ["general_type"] bldgs = buildings.to_frame(buildings.local_columns + foreign_columns) devs = [] for dev_id, d in feasibility.iterrows(): if target <= 0: break # any special logic to filter these devs? # remove new dev sqft from target target -= d.non_residential_sqft # add redeveloped sqft to target filt = "general_type == 'Retail' and parcel_id == %d" % \ d["parcel_id"] target += bldgs.query(filt).non_residential_sqft.sum() devs.append(d) if len(devs) == 0: return # record keeping - add extra columns to match building dataframe # add the buidings and demolish old buildings, and add to debug output devs = pd.DataFrame(devs, columns=buildings.local_columns) print "Building {:,} retail sqft in {:,} projects".format( devs.non_residential_sqft.sum(), len(devs)) if target > 0: print " WARNING: retail target not met" devs["form"] = "retail" devs = add_extra_columns_func(devs) add_buildings(buildings, devs) summary.add_parcel_output(devs)
def retail_developer(jobs, buildings, parcels, nodes, feasibility, settings, summary, add_extra_columns_func, net): dev_settings = settings['non_residential_developer'] all_units = dev.compute_units_to_build( len(jobs), buildings.job_spaces.sum(), dev_settings['kwargs']['target_vacancy']) target = all_units * float(dev_settings['type_splits']["Retail"]) # target here is in sqft target *= settings["building_sqft_per_job"]["HS"] feasibility = feasibility.to_frame().loc[:, "retail"] feasibility = feasibility.dropna(subset=["max_profit"]) feasibility["non_residential_sqft"] = \ feasibility.non_residential_sqft.astype("int") feasibility["retail_ratio"] = parcels.retail_ratio feasibility = feasibility.reset_index() # create features f1 = feasibility.retail_ratio / feasibility.retail_ratio.max() f2 = feasibility.max_profit / feasibility.max_profit.max() # combine features in probability function - it's like combining expense # of building the building with the market in the neighborhood p = f1 * 1.5 + f2 p = p.clip(lower=1.0/len(p)/10) print "Attempting to build {:,} retail sqft".format(target) # order by weighted random sample feasibility = feasibility.sample(frac=1.0, weights=p) bldgs = buildings.to_frame(buildings.local_columns + ["general_type"]) devs = [] for dev_id, d in feasibility.iterrows(): if target <= 0: break # any special logic to filter these devs? # remove new dev sqft from target target -= d.non_residential_sqft # add redeveloped sqft to target filt = "general_type == 'Retail' and parcel_id == %d" % \ d["parcel_id"] target += bldgs.query(filt).non_residential_sqft.sum() devs.append(d) if len(devs) == 0: return # record keeping - add extra columns to match building dataframe # add the buidings and demolish old buildings, and add to debug output devs = pd.DataFrame(devs, columns=feasibility.columns) print "Building {:,} retail sqft in {:,} projects".format( devs.non_residential_sqft.sum(), len(devs)) if target > 0: print " WARNING: retail target not met" devs["form"] = "retail" devs = add_extra_columns_func(devs) add_buildings(buildings, devs) summary.add_parcel_output(devs)
def subsidized_office_developer(feasibility, coffer, acct_settings, year, add_extra_columns_func, buildings, summary): # get the total subsidy for subsidizing office total_subsidy = coffer["vmt_com_acct"].\ total_transactions_by_subacct("regional") # get the office feasibility frame and sort by profit per sqft feasibility = feasibility.to_frame().loc[:, "office"] feasibility = feasibility.dropna(subset=["max_profit"]) feasibility["pda_id"] = feasibility.pda # filter to receiving zone feasibility = feasibility.\ query(acct_settings["vmt_settings"]["receiving_buildings_filter"]) feasibility["non_residential_sqft"] = \ feasibility.non_residential_sqft.astype("int") feasibility["max_profit_per_sqft"] = feasibility.max_profit / \ feasibility.non_residential_sqft # sorting by our choice metric as we're going to pick our devs # in order off the top feasibility = feasibility.sort_values(['max_profit_per_sqft']) # make parcel_id available feasibility = feasibility.reset_index() print "%.0f subsidy with %d developments to choose from" % ( total_subsidy, len(feasibility)) devs = [] for dev_id, d in feasibility.iterrows(): # the logic here is that we allow each dev to have a "normal" # profit per square foot and once it does we guarantee that it # gets build - we assume the planning commission for each city # enables this to happen. If a project gets enough profit already # we just allow it to compete on the open market - e.g. in the # non-subsidized office developer NORMAL_PROFIT_PER_SQFT = 70 # assume price is around $700/sqft if d.max_profit_per_sqft >= NORMAL_PROFIT_PER_SQFT: # competes in open market continue else: amt = (NORMAL_PROFIT_PER_SQFT - d.max_profit_per_sqft) * \ d.non_residential_sqft if amt > total_subsidy: # we don't have enough money to buy yet continue metadata = { "description": "Developing subsidized office building", "year": year, "non_residential_sqft": d["non_residential_sqft"], "index": dev_id } coffer["vmt_com_acct"].add_transaction(-1*amt, subaccount="regional", metadata=metadata) total_subsidy -= amt devs.append(d) if len(devs) == 0: return # record keeping - add extra columns to match building dataframe # add the buidings and demolish old buildings, and add to debug output devs = pd.DataFrame(devs, columns=feasibility.columns) print "Building {:,} subsidized office sqft in {:,} projects".format( devs.non_residential_sqft.sum(), len(devs)) devs["form"] = "office" devs = add_extra_columns_func(devs) add_buildings(buildings, devs) summary.add_parcel_output(devs)