def balanced(**kwargs): """balanced(factor_name=num_levels, [factor_name=num_levels, ..., repeat=1]) Create simple balanced factorial designs for testing. Given some factor names and the number of desired levels for each, generates a balanced factorial design in the form of a data dictionary. For example: .. ipython:: In [1]: balanced(a=2, b=3) Out[1]: {'a': ['a1', 'a1', 'a1', 'a2', 'a2', 'a2'], 'b': ['b1', 'b2', 'b3', 'b1', 'b2', 'b3']} By default it produces exactly one instance of each combination of levels, but if you want multiple replicates this can be accomplished via the `repeat` argument: .. ipython:: In [2]: balanced(a=2, b=2, repeat=2) Out[2]: {'a': ['a1', 'a1', 'a2', 'a2', 'a1', 'a1', 'a2', 'a2'], 'b': ['b1', 'b2', 'b1', 'b2', 'b1', 'b2', 'b1', 'b2']} """ repeat = kwargs.pop("repeat", 1) levels = [] names = sorted(kwargs) for name in names: level_count = kwargs[name] levels.append(["%s%s" % (name, i) for i in xrange(1, level_count + 1)]) # zip(*...) does an "unzip" values = zip(*itertools_product(*levels)) data = {} for name, value in zip(names, values): data[name] = list(value) * repeat return data
def _column_combinations(columns_per_factor): # For consistency with R, the left-most item iterates fastest: iterators = [xrange(n) for n in reversed(columns_per_factor)] for reversed_combo in itertools_product(*iterators): yield reversed_combo[::-1]