Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/build.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ on:
- docs/
- examples/
- rust/perspective-python/README.md
pull_request_target:
pull_request:
branches:
- master
workflow_dispatch:
Expand Down
145 changes: 145 additions & 0 deletions rust/perspective-python/perspective/tests/table/test_view.py
Original file line number Diff line number Diff line change
Expand Up @@ -424,6 +424,151 @@ def test_view_aggregate_mean(self):
{"__ROW_PATH__": ["a"], "y": 300 / 2},
]

def test_view_aggregate_gmv(self):
data = {
"division": [
"D1",
"D2",
"D1",
"D2",
"D1",
"D2",
"D1",
"D2",
"D1",
"D2",
"D1",
"D2",
"D1",
"D2",
"D1",
"D2",
"D1",
"D2",
"D1",
"D2",
],
"trading area": [
"A",
"B",
"C",
"D",
"E",
"A",
"B",
"C",
"D",
"E",
"A",
"B",
"C",
"D",
"E",
"A",
"B",
"C",
"D",
"E",
],
"symbol": [
"AAPL",
"GOOG",
"MSFT",
"AAPL",
"GOOG",
"MSFT",
"AAPL",
"GOOG",
"MSFT",
"AAPL",
"GOOG",
"MSFT",
"AAPL",
"GOOG",
"MSFT",
"AAPL",
"GOOG",
"MSFT",
"AAPL",
"GOOG",
],
"MV": [
1500,
1200,
1300,
1400,
1600,
1100,
1700,
1800,
1900,
2000,
-2100,
-2200,
-2300,
-2400,
-2500,
-2600,
-2700,
-2800,
-2900,
-3000,
],
}

tbl = Table(data)
view = tbl.view(
aggregates={"MV": "gmv"}, group_by=["division", "symbol"], columns=["MV"]
)

assert view.to_columns() == {
"__ROW_PATH__": [
[],
["D1"],
["D1", "AAPL"],
["D1", "GOOG"],
["D1", "MSFT"],
["D2"],
["D2", "AAPL"],
["D2", "GOOG"],
["D2", "MSFT"],
],
"MV": [10000, 5900, -2000, -3200, 700, 7100, 800, -2400, -3900],
}

def test_view_aggregate_gmv_split_by(self):
data = {
"division": [
"D1", "D2", "D1", "D2", "D1", "D2", "D1", "D2", "D1", "D2",
"D1", "D2", "D1", "D2", "D1", "D2", "D1", "D2", "D1", "D2",
],
"symbol": [
"AAPL", "GOOG", "MSFT", "AAPL", "GOOG", "MSFT", "AAPL",
"GOOG", "MSFT", "AAPL", "GOOG", "MSFT", "AAPL", "GOOG",
"MSFT", "AAPL", "GOOG", "MSFT", "AAPL", "GOOG",
],
"MV": [
1500, 1200, 1300, 1400, 1600, 1100, 1700, 1800, 1900, 2000,
-2100, -2200, -2300, -2400, -2500, -2600, -2700, -2800,
-2900, -3000,
],
}

tbl = Table(data)
view = tbl.view(
aggregates={"MV": "gmv"},
group_by=["division"],
split_by=["symbol"],
columns=["MV"],
)

assert view.to_columns() == {
"__ROW_PATH__": [[], ["D1"], ["D2"]],
"AAPL|MV": [2800, -2000, 800],
"GOOG|MV": [5600, -3200, -2400],
"MSFT|MV": [4600, 700, -3900],
}

def test_view_aggregate_mean_from_schema(self):
data = [
{"a": "a", "x": 1, "y": 200},
Expand Down
4 changes: 4 additions & 0 deletions rust/perspective-server/cpp/perspective/src/cpp/aggspec.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,9 @@ t_aggspec::agg_str() const {
case AGGTYPE_STANDARD_DEVIATION: {
return "stddev";
}
case AGGTYPE_GMV: {
return "gmv";
}
default: {
PSP_COMPLAIN_AND_ABORT("Unknown agg type");
return "unknown";
Expand Down Expand Up @@ -343,6 +346,7 @@ t_aggspec::get_output_specs(const t_schema& schema) const {
case AGGTYPE_SUM:
case AGGTYPE_SUM_ABS:
case AGGTYPE_ABS_SUM:
case AGGTYPE_GMV:
case AGGTYPE_PCT_SUM_PARENT:
case AGGTYPE_PCT_SUM_GRAND_TOTAL:
case AGGTYPE_MUL:
Expand Down
3 changes: 3 additions & 0 deletions rust/perspective-server/cpp/perspective/src/cpp/base.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -589,6 +589,9 @@ str_to_aggtype(const std::string& str) {
if (str == "stddev" || str == "standard deviation") {
return t_aggtype::AGGTYPE_STANDARD_DEVIATION;
}
if (str == "gmv") {
return t_aggtype::AGGTYPE_GMV;
}

std::stringstream ss;
ss << "Encountered unknown aggregate operation: '" << str << "'"
Expand Down
1 change: 1 addition & 0 deletions rust/perspective-server/cpp/perspective/src/cpp/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ t_config::setup(
case AGGTYPE_SUM_NOT_NULL:
case AGGTYPE_SUM_ABS:
case AGGTYPE_ABS_SUM:
case AGGTYPE_GMV:
case AGGTYPE_MUL:
case AGGTYPE_DISTINCT_COUNT:
case AGGTYPE_DISTINCT_LEAF:
Expand Down
22 changes: 22 additions & 0 deletions rust/perspective-server/cpp/perspective/src/cpp/context_two.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -77,6 +77,19 @@ t_ctx2::init() {
);

m_trees[treeidx]->init();

// Tell the tree how many of its `m_pivots` are row pivots and
// what the next missing row pivot is (if any). AGGTYPE_GMV uses
// this to roll up across row dimensions that aren't embedded in
// this particular tree — e.g. m_trees[0] has no row pivots, so
// a tree-leaf at e.g. [AAPL] needs to be partitioned by
// `row_pivots[0]` from the gstate to compute the gmv value.
const auto& row_pivots = m_config.get_row_pivots();
std::string next_row_pivot;
if (treeidx < row_pivots.size()) {
next_row_pivot = row_pivots[treeidx].colname();
}
m_trees[treeidx]->set_gmv_row_pivot_meta(treeidx, next_row_pivot);
}

m_rtraversal = std::make_shared<t_traversal>(rtree());
Expand Down Expand Up @@ -1171,6 +1184,15 @@ t_ctx2::reset(bool reset_expressions) {
);
m_trees[treeidx]->init();
m_trees[treeidx]->set_deltas_enabled(get_feature_state(CTX_FEAT_DELTA));

// See [t_ctx2::init] — gmv needs to know how many row pivots
// this particular tree carries vs. what's still in the gstate.
const auto& row_pivots = m_config.get_row_pivots();
std::string next_row_pivot;
if (treeidx < row_pivots.size()) {
next_row_pivot = row_pivots[treeidx].colname();
}
m_trees[treeidx]->set_gmv_row_pivot_meta(treeidx, next_row_pivot);
}

m_rtraversal = std::make_shared<t_traversal>(rtree());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ extract_aggregate(
case AGGTYPE_SUM:
case AGGTYPE_SUM_ABS:
case AGGTYPE_ABS_SUM:
case AGGTYPE_GMV:
case AGGTYPE_SUM_NOT_NULL:
case AGGTYPE_MUL:
case AGGTYPE_COUNT:
Expand Down
1 change: 1 addition & 0 deletions rust/perspective-server/cpp/perspective/src/cpp/server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1453,6 +1453,7 @@ ProtoServer::_handle_request(std::uint32_t client_id, Request&& req) {
number_opts.add_aggregates()->set_name("distinct count");
number_opts.add_aggregates()->set_name("dominant");
number_opts.add_aggregates()->set_name("first");
number_opts.add_aggregates()->set_name("gmv");
number_opts.add_aggregates()->set_name("high");
number_opts.add_aggregates()->set_name("low");
number_opts.add_aggregates()->set_name("max");
Expand Down
Loading
Loading