def labeled_comprehension(input, labels, index, func, out_dtype, default, pass_positions=False):
as_scalar = numpy.isscalar(index)<EOL>input = numpy.asarray(input)<EOL>if pass_positions:<EOL><INDENT>positions = numpy.arange(input.size).reshape(input.shape)<EOL><DEDENT>if labels is None:<EOL><INDENT>if index is not None:<EOL><INDENT>raise ValueError("<STR_LIT>")<EOL><DEDENT>if not pass_positions:<EOL><INDENT>return func(input.ravel())<EOL><DEDENT>else:<EOL><INDENT>return func(input.ravel(), positions.ravel())<EOL><DEDENT><DEDENT>try:<EOL><INDENT>input, labels = numpy.broadcast_arrays(input, labels)<EOL><DEDENT>except ValueError:<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>")<EOL><DEDENT>if index is None:<EOL><INDENT>if not pass_positions:<EOL><INDENT>return func(input[labels > <NUM_LIT:0>])<EOL><DEDENT>else:<EOL><INDENT>return func(input[labels > <NUM_LIT:0>], positions[labels > <NUM_LIT:0>])<EOL><DEDENT><DEDENT>index = numpy.atleast_1d(index)<EOL>if np.any(index.astype(labels.dtype).astype(index.dtype) != index):<EOL><INDENT>raise ValueError("<STR_LIT>"<EOL>"<STR_LIT>" %<EOL>(index.dtype, labels.dtype))<EOL><DEDENT>index = index.astype(labels.dtype)<EOL>lo = index.min()<EOL>hi = index.max()<EOL>mask = (labels >= lo) & (labels <= hi)<EOL>labels = labels[mask]<EOL>input = input[mask]<EOL>if pass_positions:<EOL><INDENT>positions = positions[mask]<EOL><DEDENT>label_order = labels.argsort()<EOL>labels = labels[label_order]<EOL>input = input[label_order]<EOL>if pass_positions:<EOL><INDENT>positions = positions[label_order]<EOL><DEDENT>index_order = index.argsort()<EOL>sorted_index = index[index_order]<EOL>def do_map(inputs, output):<EOL><INDENT>"""<STR_LIT>"""<EOL>nidx = sorted_index.size<EOL>lo = numpy.searchsorted(labels, sorted_index, side='<STR_LIT:left>')<EOL>hi = numpy.searchsorted(labels, sorted_index, side='<STR_LIT:right>')<EOL>for i, l, h in zip(range(nidx), lo, hi):<EOL><INDENT>if l == h:<EOL><INDENT>continue<EOL><DEDENT>output[i] = func(*[inp[l:h] for inp in inputs])<EOL><DEDENT><DEDENT>temp = numpy.empty(index.shape, out_dtype)<EOL>temp[:] = default<EOL>if not pass_positions:<EOL><INDENT>do_map([input], temp)<EOL><DEDENT>else:<EOL><INDENT>do_map([input, positions], temp)<EOL><DEDENT>output = numpy.zeros(index.shape, out_dtype)<EOL>output[index_order] = temp<EOL>if as_scalar:<EOL><INDENT>output = output[<NUM_LIT:0>]<EOL><DEDENT>return output<EOL>
Roughly equivalent to [func(input[labels == i]) for i in index].

Sequentially applies an arbitrary function (that works on array_like input)
to subsets of an n-D image array specified by `labels` and `index`.
The option exists to provide the function with positional parameters as the
second argument.

Parameters
----------
input : array_like
    Data from which to select `labels` to process.
labels : array_like or None
    Labels to objects in `input`.
    If not None, array must be same shape as `input`.
    If None, `func` is applied to raveled `input`.
index : int, sequence of ints or None
    Subset of `labels` to which to apply `func`.
    If a scalar, a single value is returned.
    If None, `func` is applied to all non-zero values of `labels`.
func : callable
    Python function to apply to `labels` from `input`.
out_dtype : dtype
    Dtype to use for `result`.
default : int, float or None
    Default return value when a element of `index` does not exist
    in `labels`.
pass_positions : bool, optional
    If True, pass linear indices to `func` as a second argument.
    Default is False.

Returns
-------
result : ndarray
    Result of applying `func` to each of `labels` to `input` in `index`.

Examples
--------
>>> a = np.array([[1, 2, 0, 0],
                  [5, 3, 0, 4],
                  [0, 0, 0, 7],
                  [9, 3, 0, 0]])
>>> from scipy import ndimage
>>> lbl, nlbl = ndimage.label(a)
>>> lbls = np.arange(1, nlbl+1)
>>> ndimage.labeled_comprehension(a, lbl, lbls, np.mean, float, 0)
array([ 2.75,  5.5 ,  6.  ])

Falling back to `default`:

>>> lbls = np.arange(1, nlbl+2)
>>> ndimage.labeled_comprehension(a, lbl, lbls, np.mean, float, -1)
array([ 2.75,  5.5 ,  6.  , -1.  ])

Passing positions:

>>> def fn(val, pos):
...     print("fn says: %s : %s" % (val, pos))
...     return (val.sum()) if (pos.sum() % 2 == 0) else (-val.sum())
...
>>> ndimage.labeled_comprehension(a, lbl, lbls, fn, float, 0, True)
fn says: [1 2 5 3] : [0 1 4 5]
fn says: [4 7] : [7 11]
fn says: [9 3] : [12 13]
array([ 11.,  11., -12.])