def other_than(groups, bools): """ Construct a Series that has booleans indicating the presence of something- or someone-else with a certain property within a group. Parameters ---------- groups : pandas.Series A column with the same index as `bools` that defines the grouping of `bools`. The `bools` Series will be used to index `groups` and then the grouped values will be counted. bools : pandas.Series A boolean Series indicating where the property of interest is present. Should have the same index as `groups`. Returns ------- others : pandas.Series A boolean Series with the same index as `groups` and `bools` indicating whether there is something- or something-else within a group with some property (as indicated by `bools`). """ counts = groups[bools].value_counts() merge_col = groups.to_frame(name="right") pipeline = tz.compose( tz.curry(pd.Series.fillna, value=False), itemgetter("left"), tz.curry(pd.DataFrame.merge, right=merge_col, how="right", left_index=True, right_on="right"), tz.curry(pd.Series.to_frame, name="left"), ) gt0 = pipeline(counts > 0) gt1 = pipeline(counts > 1) return gt1.where(bools, other=gt0)
def make_household_choices(hh_util): """ Decide on the activity pattern for each household. Parameters ---------- hh_util : dict of pandas.Series Keys will be household IDs and values will be Series mapping alternative choices to their utility. Returns ------- choices : pandas.Series Maps household ID to chosen alternative, where the alternative is a tuple of individual utilities. """ # convert hh_util dict to a few DFs with alternatives in the columns # and household IDs in the index df_func = tz.compose( pd.DataFrame.transpose, pd.DataFrame.from_dict) grouped_by_size = ( tz.valfilter(lambda x: len(x) == l, hh_util) for l in tz.unique(tz.map(len, hh_util.values()))) dfs = tz.map(df_func, grouped_by_size) # go over all the DFs and do utils_to_probs and make_choices choices = ( pd.Series( df.columns[mnl.make_choices(mnl.utils_to_probs(df))].values, index=df.index) for df in dfs) # concat all the resulting Series return pd.concat(choices)
def other_than(groups, bools): """ Construct a Series that has booleans indicating the presence of something- or someone-else with a certain property within a group. Parameters ---------- groups : pandas.Series A column with the same index as `bools` that defines the grouping of `bools`. The `bools` Series will be used to index `groups` and then the grouped values will be counted. bools : pandas.Series A boolean Series indicating where the property of interest is present. Should have the same index as `groups`. Returns ------- others : pandas.Series A boolean Series with the same index as `groups` and `bools` indicating whether there is something- or something-else within a group with some property (as indicated by `bools`). """ counts = groups[bools].value_counts() merge_col = groups.to_frame(name='right') pipeline = tz.compose( tz.curry(pd.Series.fillna, value=False), itemgetter('left'), tz.curry(pd.DataFrame.merge, right=merge_col, how='right', left_index=True, right_on='right'), tz.curry(pd.Series.to_frame, name='left')) gt0 = pipeline(counts > 0) gt1 = pipeline(counts > 1) return gt1.where(bools, other=gt0)