def _group_agg(values, bounds, f):
 if (values.ndim == 1):
  N = len(values)
  result = np.empty(len(bounds), dtype=float)
 elif (values.ndim == 2):
  (N, K) = values.shape
  result = np.empty((len(bounds), K), dtype=float)
 testagg = f(values[:min(1, len(values))])
 if (isinstance(testagg, np.ndarray) and (testagg.ndim == 2)):
  raise AssertionError('Function must reduce')
 for (i, left_bound) in enumerate(bounds):
  if (i == (len(bounds) - 1)):
   right_bound = N
  else:
   right_bound = bounds[(i + 1)]
  result[i] = f(values[left_bound:right_bound])
 return result

def _group_agg ( values , bounds , f ) : if ( values . ndim == 1 ) : N = len ( values ) result = np . empty ( len ( bounds ) , dtype = float ) elif ( values . ndim == 2 ) : ( N , K ) = values . shape result = np . empty ( ( len ( bounds ) , K ) , dtype = float ) testagg = f ( values [ : min ( 1 , len ( values ) ) ] ) if ( isinstance ( testagg , np . ndarray ) and ( testagg . ndim == 2 ) ) : raise AssertionError ( 'Function must reduce' ) for ( i , left_bound ) in enumerate ( bounds ) : if ( i == ( len ( bounds ) - 1 ) ) : right_bound = N else : right_bound = bounds [ ( i + 1 ) ] result [ i ] = f ( values [ left_bound : right_bound ] ) return result
r-style aggregator parameters values : n-length or n x k ndarray bounds : b-length ndarray f : ndarray aggregation function returns ndarray with same length as bounds array .