Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ENH] Add cummin() and cummax() functions for cumulative min/max calculation #3288

Merged
merged 27 commits into from
Jun 11, 2022
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
27 commits
Select commit Hold shift + click to select a range
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
4 changes: 3 additions & 1 deletion docs/api/index-api.rst
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,8 @@ Functions
- Count the number of NA values per column
* - :func:`cummax()`
- Calculate the cumulative maximum of values per column
* - :func:`cummin()`
- Calculate the cumulative minimum of values per column
* - :func:`cumsum()`
- Calculate the cumulative sum of values per column
* - :func:`cov()`
Expand Down Expand Up @@ -236,8 +238,8 @@ Other
count() <dt/count>
countna() <dt/countna>
cov() <dt/cov>
cummin() <dt/cummin>
cummax() <dt/cummax>
cummin() <dt/cummin>
cumsum() <dt/cumsum>
cut() <dt/cut>
dt <dt/dt>
Expand Down
3 changes: 0 additions & 3 deletions docs/releases/v1.1.0.rst
Original file line number Diff line number Diff line change
Expand Up @@ -101,9 +101,6 @@
-[fix] Reducers and row-wise functions now support :attr:`void <dt.Type.void>`
columns. [#3284]

-[fix] All the row-wise functions now support :attr:`void <dt.Type.void>`
columns. [#3284]


fread
-----
Expand Down
4 changes: 2 additions & 2 deletions src/core/documentation.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,8 @@ extern const char* doc_dt_corr;
extern const char* doc_dt_count;
extern const char* doc_dt_countna;
extern const char* doc_dt_cov;
extern const char* doc_dt_cummin;
extern const char* doc_dt_cummax;
extern const char* doc_dt_cummin;
extern const char* doc_dt_cumsum;
extern const char* doc_dt_cut;
extern const char* doc_dt_first;
Expand Down Expand Up @@ -281,8 +281,8 @@ extern const char* doc_FExpr;
extern const char* doc_FExpr_as_type;
extern const char* doc_FExpr_count;
extern const char* doc_FExpr_countna;
extern const char* doc_FExpr_cummin;
extern const char* doc_FExpr_cummax;
extern const char* doc_FExpr_cummin;
extern const char* doc_FExpr_cumsum;
extern const char* doc_FExpr_extend;
extern const char* doc_FExpr_first;
Expand Down
241 changes: 116 additions & 125 deletions src/core/expr/fexpr.cc
Original file line number Diff line number Diff line change
Expand Up @@ -295,26 +295,88 @@ DECLARE_METHOD(&PyFExpr::re_match)
// Miscellaneous
//------------------------------------------------------------------------------

oobj PyFExpr::sum(const XArgs&) {
auto sumFn = oobj::import("datatable", "sum");
return sumFn.call({this});

oobj PyFExpr::as_type(const XArgs& args) {
auto as_typeFn = oobj::import("datatable", "as_type");
oobj new_type = args[0].to_oobj();
return as_typeFn.call({this, new_type});
}

DECLARE_METHOD(&PyFExpr::sum)
->name("sum")
->docs(dt::doc_FExpr_sum);
DECLARE_METHOD(&PyFExpr::as_type)
->name("as_type")
->docs(dt::doc_FExpr_as_type)
->arg_names({"new_type"})
->n_positional_args(1)
->n_required_args(1);


oobj PyFExpr::prod(const XArgs&) {
auto prodFn = oobj::import("datatable", "prod");
return prodFn.call({this});
oobj PyFExpr::count(const XArgs&) {
auto countFn = oobj::import("datatable", "count");
return countFn.call({this});
}

DECLARE_METHOD(&PyFExpr::prod)
->name("prod")
->docs(dt::doc_FExpr_prod);
DECLARE_METHOD(&PyFExpr::count)
->name("count")
->docs(dt::doc_FExpr_count);


oobj PyFExpr::countna(const XArgs&) {
auto countnaFn = oobj::import("datatable", "countna");
return countnaFn.call({this});
}

DECLARE_METHOD(&PyFExpr::countna)
->name("countna")
->docs(dt::doc_FExpr_countna);

oobj PyFExpr::cummax(const XArgs&) {
auto cummaxFn = oobj::import("datatable", "cummax");
return cummaxFn.call({this});
}

DECLARE_METHOD(&PyFExpr::cummax)
->name("cummax")
->docs(dt::doc_FExpr_cummax);

oobj PyFExpr::cummin(const XArgs&) {
auto cumminFn = oobj::import("datatable", "cummin");
return cumminFn.call({this});
}

DECLARE_METHOD(&PyFExpr::cummin)
->name("cummin")
->docs(dt::doc_FExpr_cummin);


oobj PyFExpr::cumsum(const XArgs&) {
auto cumsumFn = oobj::import("datatable", "cumsum");
return cumsumFn.call({this});
}

DECLARE_METHOD(&PyFExpr::cumsum)
->name("cumsum")
->docs(dt::doc_FExpr_cumsum);


oobj PyFExpr::first(const XArgs&) {
auto firstFn = oobj::import("datatable", "first");
return firstFn.call({this});
}

DECLARE_METHOD(&PyFExpr::first)
->name("first")
->docs(dt::doc_FExpr_first);


oobj PyFExpr::last(const XArgs&) {
auto lastFn = oobj::import("datatable", "last");
return lastFn.call({this});
}

DECLARE_METHOD(&PyFExpr::last)
->name("last")
->docs(dt::doc_FExpr_last);

oobj PyFExpr::max(const XArgs&) {
auto maxFn = oobj::import("datatable", "max");
return maxFn.call({this});
Expand Down Expand Up @@ -358,6 +420,25 @@ DECLARE_METHOD(&PyFExpr::min)
->docs(dt::doc_FExpr_min);


oobj PyFExpr::nunique(const XArgs&) {
auto nuniqueFn = oobj::import("datatable", "nunique");
return nuniqueFn.call({this});
}

DECLARE_METHOD(&PyFExpr::nunique)
->name("nunique")
->docs(dt::doc_FExpr_nunique);

oobj PyFExpr::prod(const XArgs&) {
auto prodFn = oobj::import("datatable", "prod");
return prodFn.call({this});
}

DECLARE_METHOD(&PyFExpr::prod)
->name("prod")
->docs(dt::doc_FExpr_prod);



oobj PyFExpr::rowall(const XArgs&) {
auto rowallFn = oobj::import("datatable", "rowall");
Expand All @@ -379,6 +460,23 @@ DECLARE_METHOD(&PyFExpr::rowany)
->name("rowany")
->docs(dt::doc_FExpr_rowany);

oobj PyFExpr::rowargmax(const XArgs&) {
auto rowargmaxFn = oobj::import("datatable", "rowargmax");
return rowargmaxFn.call({this});
}

DECLARE_METHOD(&PyFExpr::rowargmax)
->name("rowargmax")
->docs(dt::doc_FExpr_rowargmax);

oobj PyFExpr::rowargmin(const XArgs&) {
auto rowargminFn = oobj::import("datatable", "rowargmin");
return rowargminFn.call({this});
}

DECLARE_METHOD(&PyFExpr::rowargmin)
->name("rowargmin")
->docs(dt::doc_FExpr_rowargmin);


oobj PyFExpr::rowcount(const XArgs&) {
Expand Down Expand Up @@ -413,14 +511,6 @@ DECLARE_METHOD(&PyFExpr::rowlast)
->docs(dt::doc_FExpr_rowlast);


oobj PyFExpr::rowargmax(const XArgs&) {
auto rowargmaxFn = oobj::import("datatable", "rowargmax");
return rowargmaxFn.call({this});
}

DECLARE_METHOD(&PyFExpr::rowargmax)
->name("rowargmax")
->docs(dt::doc_FExpr_rowargmax);


oobj PyFExpr::rowmax(const XArgs&) {
Expand All @@ -444,15 +534,6 @@ DECLARE_METHOD(&PyFExpr::rowmean)
->docs(dt::doc_FExpr_rowmean);


oobj PyFExpr::rowargmin(const XArgs&) {
auto rowargminFn = oobj::import("datatable", "rowargmin");
return rowargminFn.call({this});
}

DECLARE_METHOD(&PyFExpr::rowargmin)
->name("rowargmin")
->docs(dt::doc_FExpr_rowargmin);


oobj PyFExpr::rowmin(const XArgs&) {
auto rowminFn = oobj::import("datatable", "rowmin");
Expand All @@ -464,7 +545,6 @@ DECLARE_METHOD(&PyFExpr::rowmin)
->docs(dt::doc_FExpr_rowmin);



oobj PyFExpr::rowsd(const XArgs&) {
auto rowsdFn = oobj::import("datatable", "rowsd");
return rowsdFn.call({this});
Expand All @@ -486,7 +566,6 @@ DECLARE_METHOD(&PyFExpr::rowsum)
->docs(dt::doc_FExpr_rowsum);



oobj PyFExpr::sd(const XArgs&) {
auto sdFn = oobj::import("datatable", "sd");
return sdFn.call({this});
Expand All @@ -497,7 +576,6 @@ DECLARE_METHOD(&PyFExpr::sd)
->docs(dt::doc_FExpr_sd);



oobj PyFExpr::shift(const XArgs& args) {
auto shiftFn = oobj::import("datatable", "shift");
oobj n = args[0]? args[0].to_oobj() : py::oint(1);
Expand All @@ -510,103 +588,16 @@ DECLARE_METHOD(&PyFExpr::shift)
->arg_names({"n"})
->n_positional_or_keyword_args(1);



oobj PyFExpr::last(const XArgs&) {
auto lastFn = oobj::import("datatable", "last");
return lastFn.call({this});
}

DECLARE_METHOD(&PyFExpr::last)
->name("last")
->docs(dt::doc_FExpr_last);



oobj PyFExpr::count(const XArgs&) {
auto countFn = oobj::import("datatable", "count");
return countFn.call({this});
}

DECLARE_METHOD(&PyFExpr::count)
->name("count")
->docs(dt::doc_FExpr_count);



oobj PyFExpr::first(const XArgs&) {
auto firstFn = oobj::import("datatable", "first");
return firstFn.call({this});
}

DECLARE_METHOD(&PyFExpr::first)
->name("first")
->docs(dt::doc_FExpr_first);


oobj PyFExpr::as_type(const XArgs& args) {
auto as_typeFn = oobj::import("datatable", "as_type");
oobj new_type = args[0].to_oobj();
return as_typeFn.call({this, new_type});
}


DECLARE_METHOD(&PyFExpr::as_type)
->name("as_type")
->docs(dt::doc_FExpr_as_type)
->arg_names({"new_type"})
->n_positional_args(1)
->n_required_args(1);


oobj PyFExpr::nunique(const XArgs&) {
auto nuniqueFn = oobj::import("datatable", "nunique");
return nuniqueFn.call({this});
}

DECLARE_METHOD(&PyFExpr::nunique)
->name("nunique")
->docs(dt::doc_FExpr_nunique);


oobj PyFExpr::countna(const XArgs&) {
auto countnaFn = oobj::import("datatable", "countna");
return countnaFn.call({this});
}

DECLARE_METHOD(&PyFExpr::countna)
->name("countna")
->docs(dt::doc_FExpr_countna);


oobj PyFExpr::cumsum(const XArgs&) {
auto cumsumFn = oobj::import("datatable", "cumsum");
return cumsumFn.call({this});
}

DECLARE_METHOD(&PyFExpr::cumsum)
->name("cumsum")
->docs(dt::doc_FExpr_cumsum);


oobj PyFExpr::cummin(const XArgs&) {
auto cumminFn = oobj::import("datatable", "cummin");
return cumminFn.call({this});
oobj PyFExpr::sum(const XArgs&) {
auto sumFn = oobj::import("datatable", "sum");
return sumFn.call({this});
}

DECLARE_METHOD(&PyFExpr::cummin)
->name("cummin")
->docs(dt::doc_FExpr_cummin);
DECLARE_METHOD(&PyFExpr::sum)
->name("sum")
->docs(dt::doc_FExpr_sum);


oobj PyFExpr::cummax(const XArgs&) {
auto cummaxFn = oobj::import("datatable", "cummax");
return cummaxFn.call({this});
}

DECLARE_METHOD(&PyFExpr::cummax)
->name("cummax")
->docs(dt::doc_FExpr_cummax);

//------------------------------------------------------------------------------
// Class decoration
Expand Down
4 changes: 2 additions & 2 deletions src/datatable/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
as_type,
by,
cbind,
cummin,
cummax,
cummin,
cumsum,
cut,
fread,
Expand Down Expand Up @@ -87,8 +87,8 @@
"corr",
"count",
"cov",
"cummin",
"cummax",
"cummin",
"cumsum",
"cut",
"dt",
Expand Down
3 changes: 2 additions & 1 deletion tests/test-f.py
Original file line number Diff line number Diff line change
Expand Up @@ -455,4 +455,5 @@ def test_cummin():
assert str(dt.cummin(f.A)) == str(f.A.cummin())
assert str(dt.cummin(f[:])) == str(f[:].cummin())
DT = dt.Frame(A = [9, 8, 2, 3, None, None, 3, 0, 5, 5, 8, None, 1])
assert_equals(DT[:, f.A.cummin()], DT[:, dt.cummin(f.A)])
assert_equals(DT[:, f.A.cummin()], DT[:, dt.cummin(f.A)])