ipfn: Iterative Proportional Fitting

raw JSON →
1.4.4 verified Fri May 01 auth: no python

ipfn is a Python library for iterative proportional fitting (IPF) with N dimensions. It is used to adjust contingency tables to match known marginal totals. The current version is 1.4.4. Release cadence is low; updates are infrequent.

pip install ipfn
error TypeError: cannot unpack non-iterable int object
cause Passing a single integer as a marginal instead of an array.
fix
Wrap the integer in a numpy array: np.array([100])
error ValueError: operands could not be broadcast together with shapes
cause Marginal dimensions do not match the original matrix dimensions.
fix
Check that each marginal array length matches the corresponding axis size of Z.
error ImportError: cannot import name 'ipfn' from 'ipfn'
cause Old version of ipfn (before 1.0) used a different API.
fix
Upgrade to latest version: pip install --upgrade ipfn
gotcha The `ipfn` function modifies the input array in-place. If you need to preserve the original matrix, pass a copy.
fix Z_original = Z.copy() before calling ipfn.
gotcha Marginal totals must be provided as a list of numpy arrays, not as a single array or pandas Series.
fix Ensure marginals = [array1, array2] with matching dimensions.
gotcha The library does not validate that marginal sums match the total sum of the input matrix. Discrepancies may cause divergence.
fix Check that sum of each marginal equals sum of Z before fitting.
gotcha Convergence is not guaranteed; increase max_iteration or adjust convergence_rate if needed.
fix Set max_iteration to a higher value (e.g., 1000) and convergence_rate to a looser tolerance (e.g., 1e-4).

Basic example of iterative proportional fitting with two dimensions.

import numpy as np
import pandas as pd
from ipfn import ipfn

# Seed marginal totals
marginals = [np.array([100, 200]), np.array([150, 150])]
# Original matrix
Z = np.array([[50, 50], [150, 50]])

# Create IPF object and fit
ipf = ipfn(Z, marginals, convergence_rate=1e-5, max_iteration=100)
ipf.iterate()
print(ipf.Z)