def ipfn_df(self, df, aggregates, dimensions, weight_col='<STR_LIT>'):
steps = len(aggregates)<EOL>tables = [df]<EOL>for inc in range(steps - <NUM_LIT:1>):<EOL><INDENT>tables.append(df.copy())<EOL><DEDENT>original = df.copy()<EOL>inc = <NUM_LIT:0><EOL>for features in dimensions:<EOL><INDENT>if inc == (steps - <NUM_LIT:1>):<EOL><INDENT>table_update = df<EOL>table_current = tables[inc]<EOL><DEDENT>else:<EOL><INDENT>table_update = tables[inc + <NUM_LIT:1>]<EOL>table_current = tables[inc]<EOL><DEDENT>tmp = table_current.groupby(features)[weight_col].sum()<EOL>xijk = aggregates[inc]<EOL>feat_l = []<EOL>for feature in features:<EOL><INDENT>feat_l.append(np.unique(table_current[feature]))<EOL><DEDENT>table_update.set_index(features, inplace=True)<EOL>table_current.set_index(features, inplace=True)<EOL>for feature in product(*feat_l):<EOL><INDENT>den = tmp.loc[feature]<EOL>if den == <NUM_LIT:0>:<EOL><INDENT>table_update.loc[feature, weight_col] =table_current.loc[feature, weight_col] *xijk.loc[feature]<EOL><DEDENT>else:<EOL><INDENT>table_update.loc[feature, weight_col] =table_current.loc[feature, weight_col].astype(float) *xijk.loc[feature] / den<EOL><DEDENT><DEDENT>table_update.reset_index(inplace=True)<EOL>table_current.reset_index(inplace=True)<EOL>inc += <NUM_LIT:1><EOL>feat_l = []<EOL><DEDENT>max_conv = <NUM_LIT:0><EOL>inc = <NUM_LIT:0><EOL>for features in dimensions:<EOL><INDENT>tmp = df.groupby(features)[weight_col].sum()<EOL>ori_ijk = aggregates[inc]<EOL>temp_conv = max(abs(tmp / ori_ijk - <NUM_LIT:1>))<EOL>if temp_conv > max_conv:<EOL><INDENT>max_conv = temp_conv<EOL><DEDENT>inc += <NUM_LIT:1><EOL><DEDENT>return df, max_conv<EOL>
Runs the ipfn method from a dataframe df, aggregates/marginals and the dimension(s) preserved.
For example:
from ipfn import ipfn
import pandas as pd
age = [30, 30, 30, 30, 40, 40, 40, 40, 50, 50, 50, 50]
distance = [10,20,30,40,10,20,30,40,10,20,30,40]
m = [8., 4., 6., 7., 3., 6., 5., 2., 9., 11., 3., 1.]
df = pd.DataFrame()
df['age'] = age
df['distance'] = distance
df['total'] = m

xip = df.groupby('age')['total'].sum()
xip.loc[30] = 20
xip.loc[40] = 18
xip.loc[50] = 22
xpj = df.groupby('distance')['total'].sum()
xpj.loc[10] = 18
xpj.loc[20] = 16
xpj.loc[30] = 12
xpj.loc[40] = 14
dimensions = [['age'], ['distance']]
aggregates = [xip, xpj]

IPF = ipfn(df, aggregates, dimensions)
df = IPF.iteration()

print(df)
print(df.groupby('age')['total'].sum(), xip)