larray.ipfp
- larray.ipfp(target_sums, a=None, axes=None, maxiter=1000, threshold=0.5, stepstoabort=10, nzvzs='raise', no_convergence='raise', display_progress=False)[source]
Apply Iterative Proportional Fitting Procedure (also known as bi-proportional fitting in statistics, RAS algorithm in economics) to array a, with target_sums as targets.
- Parameters
- target_sumstuple/list of array-like
Target sums to achieve. First element must be the sum to achieve along axis 0, the second the sum along axis 1, …
- aarray-like, optional
Starting values to fit, if not given starts with an array filled with 1.
- axeslist/tuple of axes, optional
Axes on which the fitting procedure should be applied. Defaults to all axes.
- maxiterint, optional
Maximum number of iteration, defaults to 1000.
- thresholdfloat, optional
Threshold below which the result is deemed acceptable, defaults to 0.5.
- stepstoabortint, optional
Number of consecutive steps with no improvement after which to abort. Defaults to 10.
- nzvzs‘fix’, ‘warn’ or ‘raise’, optional
Behavior when detecting non zero values where the sum is zero ‘fix’: set to zero (silently) ‘warn’: set to zero and print a warning ‘raise’: raise an exception (default)
- no_convergence‘ignore’, ‘warn’ or ‘raise, optional
Behavior when the algorithm does not seem to converge. This condition is triggered both when the maximum number of iteration is reached or when the maximum absolute difference between the target and the current sums does not improve for stepstoabort iterations. ‘ignore’: return values computed up to that point (silently) ‘warn’: return values computed up to that point and print a warning ‘raise’: raise an exception (default)
- display_progressFalse, True or ‘condensed’, optional
Whether to display progress. Defaults to False. If ‘condensed’ will display progress using a denser template (using one line per iteration).
- Returns
- Array
Examples
>>> from larray import * >>> a = Axis('a=a0,a1') >>> b = Axis('b=b0,b1') >>> initial = Array([[2, 1], [1, 2]], [a, b]) >>> initial a\b b0 b1 a0 2 1 a1 1 2 >>> target_sum_along_a = Array([2, 1], b) >>> target_sum_along_a b b0 b1 2 1 >>> target_sum_along_b = Array([1, 2], a) >>> target_sum_along_b a a0 a1 1 2 >>> result = ipfp([target_sum_along_a, target_sum_along_b], initial, threshold=0.01) >>> # round result so that its display is nicer ... round(result, 2) a\b b0 b1 a0 0.85 0.15 a1 1.15 0.85
Now let us assume you have a 3D array like this:
>>> year = Axis('year=2014..2016') >>> initial = ndtest([a, b, year]) >>> initial a b\year 2014 2015 2016 a0 b0 0 1 2 a0 b1 3 4 5 a1 b0 6 7 8 a1 b1 9 10 11
and some targets for each year:
>>> btargets = initial.sum(X.a) + 1 >>> btargets b\year 2014 2015 2016 b0 7 9 11 b1 13 15 17 >>> atargets = initial.sum(X.b) + 1 >>> atargets a\year 2014 2015 2016 a0 4 6 8 a1 16 18 20
You want to apply a 2D fitting procedure for each value of that year axis. You could call ipfp within a loop on the year axis, but you can also apply the procedure for all years at once by using the axes argument. This is much faster than an explicit loop.
>>> result = ipfp([btargets, atargets], initial, axes=(X.a, X.b))