Skip to content

Commit

Permalink
Merge pull request #84 from jpmorganchase/weighted_mean_api
Browse files Browse the repository at this point in the history
Weighted mean API
  • Loading branch information
texodus authored Apr 3, 2018
2 parents c5c151c + 3b4eee9 commit c951734
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 25 deletions.
16 changes: 13 additions & 3 deletions packages/perspective/src/cpp/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -138,12 +138,22 @@ _get_aggspecs(val j_aggs)
{
std::vector<val> aggs = vecFromJSArray<val>(j_aggs);
t_aggspecvec aggspecs;
for (auto cidx = 0; cidx < aggs.size(); ++cidx)
for (auto idx = 0; idx < aggs.size(); ++idx)
{
std::vector<val> agg_row = vecFromJSArray<val>(aggs[cidx]);
std::vector<val> agg_row = vecFromJSArray<val>(aggs[idx]);
std::string name = agg_row[0].as<std::string>();
t_aggtype aggtype = agg_row[1].as<t_aggtype>();
aggspecs.push_back(t_aggspec(name, aggtype, name));

t_depvec dependencies;
std::vector<val> deps = vecFromJSArray<val>(agg_row[2]);
for (auto didx = 0; didx < deps.size(); ++didx) {
if (deps[didx].isUndefined()) {
continue;
}
std::string dep = deps[didx].as<std::string>();
dependencies.push_back(t_dep(dep, DEPTYPE_COLUMN));
}
aggspecs.push_back(t_aggspec(name, aggtype, dependencies));
}
return aggspecs;
}
Expand Down
37 changes: 15 additions & 22 deletions packages/perspective/src/js/perspective.js
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,7 @@ view.prototype.schema = async function() {
if (this.sides() > 0) {
for (let agg in this.config.aggregate) {
agg = this.config.aggregate[agg];
if (agg.column === col_name) {
if (agg.column.join(',') === col_name) {
if (["distinct count", "distinctcount", "distinct", "count"].indexOf(agg.op) > -1) {
new_schema[col_name] = "integer";
}
Expand Down Expand Up @@ -922,31 +922,24 @@ table.prototype.view = function(config) {

// Row Pivots
let aggregates = [];
if (typeof config.aggregate === "string") {
let agg_op = _string_to_aggtype[config.aggregate];
if (config.column_only) {
agg_op = __MODULE__.t_aggtype.AGGTYPE_ANY;
config.aggregate = "any";
}
let schema = this.gnode.get_tblschema();
let t_aggs = schema.columns();
for (let aidx = 0; aidx < t_aggs.size(); aidx++) {
let name = t_aggs.get(aidx);
if (name !== "psp_okey") {
aggregates.push([name, agg_op, name]);
}
}
schema.delete();
t_aggs.delete();
} else if (typeof config.aggregate === 'object') {
if (typeof config.aggregate === 'object') {
for (let aidx = 0; aidx < config.aggregate.length; aidx++) {
let agg = config.aggregate[aidx];
let agg_op = _string_to_aggtype[agg.op];
if (config.column_only) {
agg_op = __MODULE__.t_aggtype.AGGTYPE_ANY;
config.aggregate[aidx].op= "any";
}
aggregates.push([agg.column, agg_op]);
if (typeof agg.column === 'string') {
agg.column = [agg.column];
} else {
let dep_length = agg.column.length;
if ((agg.op === "weighted mean" && dep_length != 2) ||
(agg.op !== "weighted mean" && dep_length != 1)) {
throw `'${agg.op}' has incorrect arity ('${dep_length}') for column dependencies.`;
}
}
aggregates.push([agg.name || agg.column.join(","), agg_op, agg.column]);
}
} else {
let agg_op = __MODULE__.t_aggtype.AGGTYPE_DISTINCT_COUNT;
Expand All @@ -956,9 +949,9 @@ table.prototype.view = function(config) {
let schema = this.gnode.get_tblschema()
let t_aggs = schema.columns();
for (let aidx = 0; aidx < t_aggs.size(); aidx++) {
let name = t_aggs.get(aidx);
if (name !== "psp_okey") {
aggregates.push([name, agg_op, name]);
let column = t_aggs.get(aidx);
if (column !== "psp_okey") {
aggregates.push([column, agg_op, [column]]);
}
}
schema.delete();
Expand Down
11 changes: 11 additions & 0 deletions packages/perspective/test/js/internal.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,17 @@ module.exports = (perspective) => {

describe("Internal API", function () {

it("['z'], sum with new column syntax with wrong column arity errors", async function () {
var table = perspective.table(arrow.slice());
let anon = function() {
let view = table.view({
row_pivot: ['char'],
aggregate: [{op: 'sum', column:['f16', 'f32']}],
});
}
expect(anon).toThrow();
});

it("Arrow schema types are mapped correctly", async function () {
// This only works for non parallel
var table = perspective.table(arrow.slice());
Expand Down
42 changes: 42 additions & 0 deletions packages/perspective/test/js/pivots.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,15 @@ var meta = {
'z': "boolean"
};


var data2 = [
{'x': 1, 'y':1, 'z': true},
{'x': 2, 'y':1, 'z': false},
{'x': 3, 'y':2, 'z': true},
{'x': 4, 'y':2, 'z': false}
];


module.exports = (perspective) => {

describe("Aggregate", function() {
Expand All @@ -39,6 +48,39 @@ module.exports = (perspective) => {
expect(answer).toEqual(result2);
});

it("['z'], sum with new column syntax", async function () {
var table = perspective.table(data);
var view = table.view({
row_pivot: ['z'],
aggregate: [{op: 'sum', column:['x']}],
});
var answer = [
{__ROW_PATH__: [], x: 10},
{__ROW_PATH__: [ false ], x: 6},
{__ROW_PATH__: [ true ], x: 4},
];
let result2 = await view.to_json();
expect(answer).toEqual(result2);
});

it("['z'], weighted_mean", async function () {
var table = perspective.table(data2);
var view = table.view({
row_pivot: ['z'],
aggregate: [{op: 'mean', column:['x']},
{op: 'weighted mean', column:['x', 'y']}
],
});
var answer = [
{__ROW_PATH__: [], x: 2.5, "x,y": 2.8333333333333335},
{__ROW_PATH__: [ false ], x: 3, "x,y": 3.3333333333333335},
{__ROW_PATH__: [ true ], x: 2, "x,y": 2.3333333333333335},
];
let result2 = await view.to_json();
expect(answer).toEqual(result2);
});


it("['z'], mean", async function () {
var table = perspective.table(data);
var view = table.view({
Expand Down

0 comments on commit c951734

Please sign in to comment.