def run_feasibility(parcels, parcel_price_callback, parcel_use_allowed_callback, residential_to_yearly=True): """ Execute development feasibility on all parcels Parameters ---------- parcels : DataFrame Wrapper The data frame wrapper for the parcel data parcel_price_callback : function A callback which takes each use of the pro forma and returns a series with index as parcel_id and value as yearly_rent parcel_use_allowed_callback : function A callback which takes each form of the pro forma and returns a series with index as parcel_id and value and boolean whether the form is allowed on the parcel residential_to_yearly : boolean (default true) Whether to use the cap rate to convert the residential price from total sales price per sqft to rent per sqft Returns ------- Adds a table called feasibility to the sim object (returns nothing) """ pf = sqftproforma.SqFtProForma() df = parcels.to_frame() # add prices for each use for use in pf.config.uses: df[use] = parcel_price_callback(use) # convert from cost to yearly rent if residential_to_yearly: df["residential"] *= pf.config.cap_rate print "Describe of the yearly rent by use" print df[pf.config.uses].describe() d = {} for form in pf.config.forms: print "Computing feasibility for form %s" % form d[form] = pf.lookup(form, df[parcel_use_allowed_callback(form)]) far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1) sim.add_table("feasibility", far_predictions)
def nonresidential_proforma(form, devtype_id, use, parking_rate): print form parcels = sim.get_table('parcels').to_frame() residential_to_yearly = False parcel_filter = settings['feasibility']['parcel_filter'] #parcel_filter = None pfc = sqftproforma.SqFtProFormaConfig() pfc.forms = {form: {use: 1.0}} pfc.uses = [use] pfc.residential_uses = [False] pfc.parking_rates = {use: parking_rate} if use == 'retail': pfc.costs = {use: [160.0, 175.0, 200.0, 230.0]} elif use == 'industrial': pfc.costs = {use: [140.0, 175.0, 200.0, 230.0]} else: #office pfc.costs = {use: [160.0, 175.0, 200.0, 230.0]} #Fees fee_schedule_devtype = fee_schedule[fee_schedule.development_type_id == devtype_id] parcel_fee_schedule_devtype = pd.merge(parcel_fee_schedule, fee_schedule_devtype, left_on='fee_schedule_id', right_on='fee_schedule_id') parcel_fee_schedule_devtype[ 'development_fee_per_unit'] = parcel_fee_schedule_devtype.development_fee_per_unit_space_initial * parcel_fee_schedule_devtype.portion parcel_fees_processed = parcel_fee_schedule_devtype.groupby( 'parcel_id').development_fee_per_unit.sum() fees = pd.Series(data=parcel_fees_processed, index=parcels.index).fillna(0) pf = sqftproforma.SqFtProForma(pfc) fees = fees * pf.config.cap_rate return run_proforma_lookup(parcels, fees, pf, use, form, residential_to_yearly, parcel_filter=parcel_filter)
def run_feasibility(parcels, parcel_price_callback, parcel_use_allowed_callback, residential_to_yearly=True, parcel_filter=None, only_built=True, forms_to_test=None, config=None, pass_through=[], simple_zoning=False): """ Execute development feasibility on all parcels Parameters ---------- parcels : DataFrame Wrapper The data frame wrapper for the parcel data parcel_price_callback : function A callback which takes each use of the pro forma and returns a series with index as parcel_id and value as yearly_rent parcel_use_allowed_callback : function A callback which takes each form of the pro forma and returns a series with index as parcel_id and value and boolean whether the form is allowed on the parcel residential_to_yearly : boolean (default true) Whether to use the cap rate to convert the residential price from total sales price per sqft to rent per sqft parcel_filter : string A filter to apply to the parcels data frame to remove parcels from consideration - is typically used to remove parcels with buildings older than a certain date for historical preservation, but is generally useful only_built : boolean Only return those buildings that are profitable - only those buildings that "will be built" forms_to_test : list of strings (optional) Pass the list of the names of forms to test for feasibility - if set to None will use all the forms available in ProFormaConfig config : SqFtProFormaConfig configuration object. Optional. Defaults to None pass_through : list of strings Will be passed to the feasibility lookup function - is used to pass variables from the parcel dataframe to the output dataframe, usually for debugging simple_zoning: boolean, optional This can be set to use only max_dua for residential and max_far for non-residential. This can be handy if you want to deal with zoning outside of the developer model. Returns ------- Adds a table called feasibility to the sim object (returns nothing) """ pf = sqftproforma.SqFtProForma(config) if config \ else sqftproforma.SqFtProForma() df = parcels.to_frame() if parcel_filter: df = df.query(parcel_filter) # add prices for each use for use in pf.config.uses: # assume we can get the 80th percentile price for new development df[use] = parcel_price_callback(use) # convert from cost to yearly rent if residential_to_yearly: df["residential"] *= pf.config.cap_rate print "Describe of the yearly rent by use" print df[pf.config.uses].describe() d = {} forms = forms_to_test or pf.config.forms for form in forms: print "Computing feasibility for form %s" % form allowed = parcel_use_allowed_callback(form).loc[df.index] newdf = df[allowed] if simple_zoning: if form == "residential": # these are new computed in the effective max_dua method newdf["max_far"] = pd.Series() newdf["max_height"] = pd.Series() else: # these are new computed in the effective max_far method newdf["max_dua"] = pd.Series() newdf["max_height"] = pd.Series() d[form] = pf.lookup(form, newdf, only_built=only_built, pass_through=pass_through) if residential_to_yearly and "residential" in pass_through: d[form]["residential"] /= pf.config.cap_rate far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1) orca.add_table("feasibility", far_predictions)
def run_feasibility(parcels, parcel_price_callback, parcel_use_allowed_callback, residential_to_yearly=True, parcel_filter=None, only_built=True, forms_to_test=None, config=None, pass_through=[]): """ Execute development feasibility on all parcels Parameters ---------- parcels : DataFrame Wrapper The data frame wrapper for the parcel data parcel_price_callback : function A callback which takes each use of the pro forma and returns a series with index as parcel_id and value as yearly_rent parcel_use_allowed_callback : function A callback which takes each form of the pro forma and returns a series with index as parcel_id and value and boolean whether the form is allowed on the parcel residential_to_yearly : boolean (default true) Whether to use the cap rate to convert the residential price from total sales price per sqft to rent per sqft parcel_filter : string A filter to apply to the parcels data frame to remove parcels from consideration - is typically used to remove parcels with buildings older than a certain date for historical preservation, but is generally useful only_built : boolean Only return those buildings that are profitable - only those buildings that "will be built" forms_to_test : list of strings (optional) Pass the list of the names of forms to test for feasibility - if set to None will use all the forms available in ProFormaConfig config : SqFtProFormaConfig configuration object. Optional. Defaults to None pass_through : list of strings Will be passed to the feasibility lookup function - is used to pass variables from the parcel dataframe to the output dataframe, usually for debugging Returns ------- Adds a table called feasibility to the sim object (returns nothing) """ pf = sqftproforma.SqFtProForma(config) if config \ else sqftproforma.SqFtProForma() df = parcels.to_frame() if parcel_filter: df = df.query(parcel_filter) #print df.loc[765403] #df.to_csv("select_parcels.csv") # add prices for each use for use in pf.config.uses: # assume we can get the 80th percentile price for new development df[use] = parcel_price_callback(use) # convert from cost to yearly rent if residential_to_yearly: df["residential"] *= pf.config.cap_rate print "Describe of the yearly rent by use" print df[pf.config.uses].describe() d = {} forms = forms_to_test or pf.config.forms for form in forms: print "Computing feasibility for form %s" % form allowed = parcel_use_allowed_callback(form).loc[df.index] #allowed.to_csv(str(form) + "allow.csv") #df[allowed].to_csv(str(form) + "allow.csv") d[form] = pf.lookup(form, df[allowed], only_built=only_built, pass_through=pass_through) #d[form].to_csv(str(form) + "dform.csv") if residential_to_yearly and "residential" in pass_through: d[form]["residential"] /= pf.config.cap_rate far_predictions = pd.concat(d.values(), keys=d.keys(), axis=1) far_predictions['residential'].to_csv("residential_far_prediction.csv") far_predictions['retail'].to_csv("retail_far_prediction.csv") far_predictions['office'].to_csv("office_far_prediction.csv") #far_predictions.to_csv("far_prediction.csv") far_predictions['residential'].max_profit = far_predictions['residential'].max_profit / np.power(far_predictions['residential'].max_profit_far*far_predictions['residential'].shape_area,1) far_predictions['industrial'].max_profit = far_predictions['industrial'].max_profit / np.power(far_predictions['industrial'].max_profit_far*far_predictions['industrial'].shape_area,1) far_predictions['retail'].max_profit = far_predictions['retail'].max_profit / np.power(far_predictions['retail'].max_profit_far*far_predictions['retail'].shape_area,1) far_predictions['office'].max_profit = far_predictions['office'].max_profit / np.power(far_predictions['office'].max_profit_far*far_predictions['office'].shape_area,1) #far_predictions['residential'].max_profit = np.divide(far_predictions['residential'].max_profit,far_predictions['residential'].max_dua) #far_predictions['residential'].max_profit[far_predictions['residential'].max_profit==-np.inf] = np.nan sim.add_table("feasibility", far_predictions)