package water.rapids.ast.prims.advmath; import water.fvec.Frame; import water.fvec.Vec; import water.rapids.Env; import water.rapids.vals.ValNum; import water.rapids.ast.AstPrimitive; import water.rapids.ast.AstRoot; import water.util.ArrayUtils; import water.util.MRUtils; /** * Find the mode: the most popular element. */ public class AstMode extends AstPrimitive { @Override public String[] args() { return new String[]{"ary"}; } @Override public String str() { return "mode"; } @Override public int nargs() { return 1 + 1; } // (mode ary) @Override public ValNum apply(Env env, Env.StackHelp stk, AstRoot asts[]) { Frame fr = stk.track(asts[1].exec(env)).getFrame(); if (fr.numCols() != 1 || !fr.anyVec().isCategorical()) throw new IllegalArgumentException("mode only works on a single categorical column"); return new ValNum(mode(fr.anyVec())); } public static int mode(Vec v) { if (v.isNumeric()) { MRUtils.Dist t = new MRUtils.Dist().doAll(v); int mode = ArrayUtils.maxIndex(t.dist()); return (int) t.keys()[mode]; } double[] dist = new MRUtils.ClassDist(v).doAll(v).dist(); return ArrayUtils.maxIndex(dist); } }