parameters: (input, labels, index, func, out_dtype, default, pass_positions=False)
return_statement: return output
docstring: 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.,   0.])
docstring_summary: Roughly equivalent to [func(input[labels == i]) for i in index].
docstring_tokens: Roughly equivalent to [ func ( input [ labels == i ] ) for i in index ] .
function: def labeled_comprehension(input, labels, index, func, out_dtype, default, pass_positions=False):
      """
      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.,   0.])
  
      """
  
      as_scalar = numpy.isscalar(index)
      input = numpy.asarray(input)
  
      if pass_positions:
          positions = numpy.arange(input.size).reshape(input.shape)
  
      if labels is None:
          if index is not None:
              raise ValueError("index without defined labels")
          if not pass_positions:
              return func(input.ravel())
          else:
              return func(input.ravel(), positions.ravel())
  
      try:
          input, labels = numpy.broadcast_arrays(input, labels)
      except ValueError:
          raise ValueError("input and labels must have the same shape "
                              "(excepting dimensions with width 1)")
  
      if index is None:
          if not pass_positions:
              return func(input[labels > 0])
          else:
              return func(input[labels > 0], positions[labels > 0])
  
      index = numpy.atleast_1d(index)
      if np.any(index.astype(labels.dtype).astype(index.dtype) != index):
          raise ValueError("Cannot convert index values from <%s> to <%s> "
                              "(labels' type) without loss of precision" %
                              (index.dtype, labels.dtype))
  
      index = index.astype(labels.dtype)
  
      # optimization: find min/max in index, and select those parts of labels, input, and positions
      lo = index.min()
      hi = index.max()
      mask = (labels >= lo) & (labels <= hi)
  
      # this also ravels the arrays
      labels = labels[mask]
      input = input[mask]
      if pass_positions:
          positions = positions[mask]
  
      # sort everything by labels
      label_order = labels.argsort()
      labels = labels[label_order]
      input = input[label_order]
      if pass_positions:
          positions = positions[label_order]
  
      index_order = index.argsort()
      sorted_index = index[index_order]
  
      def do_map(inputs, output):
          """labels must be sorted"""
          nidx = sorted_index.size
  
          # Find boundaries for each stretch of constant labels
          # This could be faster, but we already paid N log N to sort labels.
          lo = numpy.searchsorted(labels, sorted_index, side='left')
          hi = numpy.searchsorted(labels, sorted_index, side='right')
  
          for i, l, h in zip(range(nidx), lo, hi):
              if l == h:
                  continue
              output[i] = func(*[inp[l:h] for inp in inputs])
  
      temp = numpy.empty(index.shape, out_dtype)
      temp[:] = default
      if not pass_positions:
          do_map([input], temp)
      else:
          do_map([input, positions], temp)
  
      output = numpy.zeros(index.shape, out_dtype)
      output[index_order] = temp
      if as_scalar:
          output = output[0]
  
      return output
function_tokens: def labeled_comprehension ( input , labels , index , func , out_dtype , default , pass_positions = False ) : as_scalar = numpy . isscalar ( index ) input = numpy . asarray ( input ) if pass_positions : positions = numpy . arange ( input . size ) . reshape ( input . shape ) if labels is None : if index is not None : raise ValueError ( "index without defined labels" ) if not pass_positions : return func ( input . ravel ( ) ) else : return func ( input . ravel ( ) , positions . ravel ( ) ) try : input , labels = numpy . broadcast_arrays ( input , labels ) except ValueError : raise ValueError ( "input and labels must have the same shape " "(excepting dimensions with width 1)" ) if index is None : if not pass_positions : return func ( input [ labels > 0 ] ) else : return func ( input [ labels > 0 ] , positions [ labels > 0 ] ) index = numpy . atleast_1d ( index ) if np . any ( index . astype ( labels . dtype ) . astype ( index . dtype ) != index ) : raise ValueError ( "Cannot convert index values from <%s> to <%s> " "(labels' type) without loss of precision" % ( index . dtype , labels . dtype ) ) index = index . astype ( labels . dtype ) # optimization: find min/max in index, and select those parts of labels, input, and positions lo = index . min ( ) hi = index . max ( ) mask = ( labels >= lo ) & ( labels <= hi ) # this also ravels the arrays labels = labels [ mask ] input = input [ mask ] if pass_positions : positions = positions [ mask ] # sort everything by labels label_order = labels . argsort ( ) labels = labels [ label_order ] input = input [ label_order ] if pass_positions : positions = positions [ label_order ] index_order = index . argsort ( ) sorted_index = index [ index_order ] def do_map ( inputs , output ) : """labels must be sorted""" nidx = sorted_index . size # Find boundaries for each stretch of constant labels # This could be faster, but we already paid N log N to sort labels. lo = numpy . searchsorted ( labels , sorted_index , side = 'left' ) hi = numpy . searchsorted ( labels , sorted_index , side = 'right' ) for i , l , h in zip ( range ( nidx ) , lo , hi ) : if l == h : continue output [ i ] = func ( * [ inp [ l : h ] for inp in inputs ] ) temp = numpy . empty ( index . shape , out_dtype ) temp [ : ] = default if not pass_positions : do_map ( [ input ] , temp ) else : do_map ( [ input , positions ] , temp ) output = numpy . zeros ( index . shape , out_dtype ) output [ index_order ] = temp if as_scalar : output = output [ 0 ] return output