AveragedValue aggregator for Optional type?

20 views
Skip to first unread message

Vincent Grosbois

unread,
Apr 27, 2016, 5:12:08 PM4/27/16
to algebird
hi !
is there an average aggregator (as in, com.twitter.algebird.AveragedValue) that works for scala Option types, much like Hive works by default?
For instance in Hive, averaging 1, 3 and NULL, will return 2. Averaging NULL, NULL and NULL will return NULL.
Is there a class to do this with Algebird or should I roll my own aggregator, based on the AveragedValue aggregator?

Thanks!

P. Oscar Boykin

unread,
Apr 27, 2016, 9:21:23 PM4/27/16
to Vincent Grosbois, algebird
you can geek out a bit here. Let's assume you have Int as you seem to above:

val intAve = AveragedValue.numericAggregator[Int]
// Now we actually have Option[Int], so we add a second aggregator
val unitAggregator = Aggregator.fromMoniod[Unit]
// now combine:

val opt: MonoidAggregator[Option[Int], _, Option[Double]] = unitAggregator.either(intAve)
  .composePrepare { opt: Option[Int] =>
    opt match {
      case None => Left(()) // unit
      case Some(i) => Right(i)
    }
  }
  .andThenPresent { case (_, av) =>
    if (av.count == 0L) None else Some(av.value)
  }

something like that should work.

--
You received this message because you are subscribed to the Google Groups "algebird" group.
To unsubscribe from this group and stop receiving emails from it, send an email to algebird+u...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Danielle Sucher

unread,
Apr 27, 2016, 9:39:14 PM4/27/16
to P. Oscar Boykin, Vincent Grosbois, algebird
Hm, I was thinking:

val agg = AveragedValue.numericAggregator[Int].lift

val optionAgg = new MonoidAggregator[Option[Int], Option[AveragedValue], Option[Double]] {
  def prepare(input: Option[Int]): Option[AveragedValue] = input.flatMap(agg.prepare(_))
  def present(reduction: Option[AveragedValue]): Option[Double] = agg.present(reduction)
  def monoid = agg.monoid
}

P. Oscar Boykin

unread,
Apr 27, 2016, 9:42:34 PM4/27/16
to Danielle Sucher, Vincent Grosbois, algebird
yeah, that is nicer. I was trying to do it all with combinators, but it is clumsy.

I prefer yours.

Avi Bryant

unread,
Apr 27, 2016, 10:29:53 PM4/27/16
to P. Oscar Boykin, Danielle Sucher, Vincent Grosbois, algebird
If we're playing golf, isn't this just

val agg = AveragedValue.numericAggregator[Int].lift.sumBefore ?

P. Oscar Boykin

unread,
Apr 27, 2016, 11:00:17 PM4/27/16
to Avi Bryant, Danielle Sucher, Vincent Grosbois, algebird
I thought he wanted to preserve the Option on the result if all were None. But maybe that was just how Hive did it and not important.

The type of hive's average function seems something like: Iterable[Option[Number]] => Option[Number]

P. Oscar Boykin

unread,
Apr 27, 2016, 11:04:46 PM4/27/16
to Avi Bryant, Danielle Sucher, Vincent Grosbois, algebird
My mental type checker was off. Avi's is right.
Reply all
Reply to author
Forward
0 new messages