From 4c4b05de533371e563ed09c44156ee8627ac7d36 Mon Sep 17 00:00:00 2001 From: samukweku Date: Mon, 13 Mar 2023 09:52:47 +1100 Subject: [PATCH 01/53] add header for isna --- src/core/expr/funary/floating/fexpr_isna.h | 41 ++++++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 src/core/expr/funary/floating/fexpr_isna.h diff --git a/src/core/expr/funary/floating/fexpr_isna.h b/src/core/expr/funary/floating/fexpr_isna.h new file mode 100644 index 0000000000..2d77c707e0 --- /dev/null +++ b/src/core/expr/funary/floating/fexpr_isna.h @@ -0,0 +1,41 @@ +//------------------------------------------------------------------------------ +// Copyright 2023 H2O.ai +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//------------------------------------------------------------------------------ +#ifndef dt_EXPR_FLOATING_FEXPR_ISNA_h +#define dt_EXPR_FLOATING_FEXPR_ISNA_h +#include "expr/fexpr_func_unary.h" +namespace dt { +namespace expr { + + + +class FExpr_ISNA : public FExpr_FuncUnary { + public: + using FExpr_FuncUnary::FExpr_FuncUnary; + std::string name() const override; + Column evaluate1(Column&& col) const override; +}; + + + + +}} // namespace dt::expr +#endif From c609de13e158804bc3231df3c89ef9d30264662c Mon Sep 17 00:00:00 2001 From: samukweku Date: Mon, 13 Mar 2023 23:43:12 +1100 Subject: [PATCH 02/53] implemenation of isna fexpr --- docs/api/math/isna.rst | 42 ++++++++- src/core/expr/fexpr_isna.cc | 89 +++++++++++++++++++ .../expr/{funary/floating => }/fexpr_isna.h | 20 ++--- src/core/expr/fnary/rowcount.cc | 22 ++++- src/core/expr/funary/floating.cc | 45 ---------- src/core/expr/funary/pyfn.cc | 1 - src/core/expr/funary/pyfn.h | 1 - src/core/expr/funary/umaker.cc | 1 - src/core/expr/funary/umaker.h | 1 - src/core/expr/op.h | 1 - src/datatable/__init__.py | 1 - src/datatable/expr/expr.py | 1 - src/datatable/expr/math.py | 2 +- src/datatable/math.py | 25 +++++- tests/ijby/test-assign.py | 2 +- tests/math/test-isna.py | 2 +- tests/munging/test-delete.py | 3 +- tests/munging/test-dt-rows.py | 2 +- tests/test-import-all.py | 2 +- 19 files changed, 191 insertions(+), 72 deletions(-) create mode 100644 src/core/expr/fexpr_isna.cc rename src/core/expr/{funary/floating => }/fexpr_isna.h (80%) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 713a7bd166..d76c4e4740 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -1,8 +1,48 @@ .. xfunction:: datatable.math.isna - :src: src/core/expr/funary/floating.cc resolve_op_isna + :src: src/core/expr/fexpr_isna.cc pyfn_isna :tests: tests/math/test-isna.py :cvar: doc_math_isna :signature: isna(x) Returns `True` if the argument is NA, and `False` otherwise. + + Parameters + ---------- + cols: FExpr + Input columns. + + return: Expr + f-expression having one row, and the same names and number of columns + as in `cols`. All the returned column stypes are `int8`. + + Examples + -------- + + .. code-block:: python + + >>> from datatable import dt, f + >>> from datetime import datetime + >>> DT = dt.Frame({'age': [5.0, 6.0, None], + ... 'born': [None, + ... datetime(1939, 5, 27, 0, 0), + ... datetime(1940, 4, 25, 0, 0)], + ... 'name': ['Alfred', 'Batman', ''], + ... 'toy': [None, 'Batmobile', 'Joker']}) + >>> DT + | age born name toy + | float64 time64 str32 str32 + -- + ------- ------------------- ------ --------- + 0 | 5 NA Alfred NA + 1 | 6 1939-05-27T00:00:00 Batman Batmobile + 2 | NA 1940-04-25T00:00:00 Joker + [3 rows x 4 columns] + >>> DT[:, dt.math.isna(f[:])] + | age born name toy + | bool8 bool8 bool8 bool8 + -- + ----- ----- ----- ----- + 0 | 0 1 0 1 + 1 | 0 0 0 0 + 2 | 1 0 0 0 + [3 rows x 4 columns] + diff --git a/src/core/expr/fexpr_isna.cc b/src/core/expr/fexpr_isna.cc new file mode 100644 index 0000000000..dfc08e9597 --- /dev/null +++ b/src/core/expr/fexpr_isna.cc @@ -0,0 +1,89 @@ +//------------------------------------------------------------------------------ +// Copyright 2023 H2O.ai +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//------------------------------------------------------------------------------ +#include "column/isna.h" +#include "column/const.h" +#include "documentation.h" +#include "expr/fexpr_column.h" +#include "expr/fexpr_isna.h" +#include "expr/eval_context.h" +#include "expr/workframe.h" +#include "python/xargs.h" +namespace dt { +namespace expr { + +FExpr_ISNA::FExpr_ISNA(ptrExpr&& arg) : + arg_(std::move(arg)) + {} + + +std::string FExpr_ISNA::repr() const { + std::string out = "isna"; + out += '('; + out += arg_->repr(); + out += ')'; + return out; +} + +static Column make_isna_col(Column&& col) { + switch (col.stype()) { + case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); + default: throw RuntimeError(); + } +} + + +Workframe FExpr_ISNA::evaluate_n(EvalContext& ctx) const { + Workframe wf = arg_->evaluate_n(ctx); + + for (size_t i = 0; i < wf.ncols(); ++i) { + Column coli = make_isna_col(wf.retrieve_column(i)); + wf.replace_column(i, std::move(coli)); + } + + return wf; +} + + +static py::oobj pyfn_isna(const py::XArgs& args) { + auto isna = args[0].to_oobj(); + return PyFExpr::make(new FExpr_ISNA(as_fexpr(isna))); +} + +DECLARE_PYFN(&pyfn_isna) + ->name("isna") + //->docs(doc_dt_isna) + ->arg_names({"cols"}) + ->n_positional_args(1) + ->n_required_args(1); + +}} // dt::expr diff --git a/src/core/expr/funary/floating/fexpr_isna.h b/src/core/expr/fexpr_isna.h similarity index 80% rename from src/core/expr/funary/floating/fexpr_isna.h rename to src/core/expr/fexpr_isna.h index 2d77c707e0..295758edc2 100644 --- a/src/core/expr/funary/floating/fexpr_isna.h +++ b/src/core/expr/fexpr_isna.h @@ -19,23 +19,23 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //------------------------------------------------------------------------------ -#ifndef dt_EXPR_FLOATING_FEXPR_ISNA_h -#define dt_EXPR_FLOATING_FEXPR_ISNA_h -#include "expr/fexpr_func_unary.h" +#ifndef dt_EXPR_FEXPR_ISNA_h +#define dt_EXPR_FEXPR_ISNA_h +#include "expr/fexpr_func.h" namespace dt { namespace expr { +class FExpr_ISNA : public FExpr_Func { + private: + ptrExpr arg_; -class FExpr_ISNA : public FExpr_FuncUnary { public: - using FExpr_FuncUnary::FExpr_FuncUnary; - std::string name() const override; - Column evaluate1(Column&& col) const override; + FExpr_ISNA(ptrExpr&& arg); + std::string repr() const override; + Workframe evaluate_n(EvalContext& ctx) const override; }; - - -}} // namespace dt::expr +}} // dt::expr #endif diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index a750a7f69a..6c5d235f1d 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -20,11 +20,11 @@ // IN THE SOFTWARE. //------------------------------------------------------------------------------ #include +#include "column/isna.h" #include "column/const.h" #include "column/func_nary.h" #include "documentation.h" #include "expr/fnary/fnary.h" -#include "expr/funary/umaker.h" #include "python/xargs.h" namespace dt { namespace expr { @@ -49,6 +49,23 @@ static bool op_rowcount(size_t i, int32_t* out, const colvec& columns) { return true; } +static Column make_isna_col(Column&& col) { + switch (col.stype()) { + case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); + default: throw RuntimeError(); + } +} Column FExpr_RowCount::apply_function(colvec&& columns, const size_t nrows, @@ -59,7 +76,8 @@ Column FExpr_RowCount::apply_function(colvec&& columns, } for (size_t i = 0; i < columns.size(); ++i) { xassert(columns[i].nrows() == nrows); - columns[i] = unaryop(Op::ISNA, std::move(columns[i])); + columns[i] = make_isna_col(std::move(columns[i])); + //columns[i] = unaryop(Op::ISNA, std::move(columns[i])); } return Column(new FuncNary_ColumnImpl( std::move(columns), op_rowcount, nrows, SType::INT32)); diff --git a/src/core/expr/funary/floating.cc b/src/core/expr/funary/floating.cc index 2a8165db44..04b332640a 100644 --- a/src/core/expr/funary/floating.cc +++ b/src/core/expr/funary/floating.cc @@ -124,51 +124,6 @@ umaker_ptr resolve_op_sign(SType stype) { } } - - - -//------------------------------------------------------------------------------ -// Op::ISNA -//------------------------------------------------------------------------------ - -py::PKArgs args_isna(1, 0, 0, false, false, {"x"}, "isna", dt::doc_math_isna); - - -template -class isna_umaker : public umaker { - public: - Column compute(Column&& col) const override { - return Column(new Isna_ColumnImpl(std::move(col))); - } -}; - - -umaker_ptr resolve_op_isna(SType stype) { - switch (stype) { - case SType::VOID: { - return umaker_ptr(new umaker_const( - Const_ColumnImpl::make_bool_column(1, true))); - } - case SType::BOOL: - case SType::INT8: return umaker_ptr(new isna_umaker()); - case SType::INT16: return umaker_ptr(new isna_umaker()); - case SType::DATE32: - case SType::INT32: return umaker_ptr(new isna_umaker()); - case SType::TIME64: - case SType::INT64: return umaker_ptr(new isna_umaker()); - case SType::FLOAT32: return umaker_ptr(new isna_umaker()); - case SType::FLOAT64: return umaker_ptr(new isna_umaker()); - case SType::STR32: - case SType::STR64: return umaker_ptr(new isna_umaker()); - default: - throw TypeError() << "Function `isna` cannot be applied to a " - "column of type `" << stype << "`"; - } -} - - - - //------------------------------------------------------------------------------ // Op::ISINF //------------------------------------------------------------------------------ diff --git a/src/core/expr/funary/pyfn.cc b/src/core/expr/funary/pyfn.cc index 844cd03bea..f7ee7cae80 100644 --- a/src/core/expr/funary/pyfn.cc +++ b/src/core/expr/funary/pyfn.cc @@ -150,7 +150,6 @@ void py::DatatableModule::init_funary() // Floating-point FUNARY(args_isfinite, Op::ISFINITE); FUNARY(args_isinf, Op::ISINF); - FUNARY(args_isna, Op::ISNA); FUNARY(args_ceil, Op::CEIL); FUNARY(args_abs, Op::ABS); FUNARY(args_fabs, Op::FABS); diff --git a/src/core/expr/funary/pyfn.h b/src/core/expr/funary/pyfn.h index 274be5690a..e6e009fde9 100644 --- a/src/core/expr/funary/pyfn.h +++ b/src/core/expr/funary/pyfn.h @@ -65,7 +65,6 @@ extern py::PKArgs args_lgamma; // Floating-point extern py::PKArgs args_isfinite; extern py::PKArgs args_isinf; -extern py::PKArgs args_isna; extern py::PKArgs args_ceil; extern py::PKArgs args_copysign; extern py::PKArgs args_abs; diff --git a/src/core/expr/funary/umaker.cc b/src/core/expr/funary/umaker.cc index 0bd9867f8e..663673be08 100644 --- a/src/core/expr/funary/umaker.cc +++ b/src/core/expr/funary/umaker.cc @@ -104,7 +104,6 @@ umaker_ptr resolve_op(Op opcode, SType stype) // Math: floating-point case Op::ISFINITE: return resolve_op_isfinite(stype); case Op::ISINF: return resolve_op_isinf(stype); - case Op::ISNA: return resolve_op_isna(stype); case Op::CEIL: return resolve_op_ceil(stype); case Op::ABS: return resolve_op_abs(stype); case Op::FABS: return resolve_op_fabs(stype); diff --git a/src/core/expr/funary/umaker.h b/src/core/expr/funary/umaker.h index 30031729a9..9d42b00cf1 100644 --- a/src/core/expr/funary/umaker.h +++ b/src/core/expr/funary/umaker.h @@ -125,7 +125,6 @@ umaker_ptr resolve_op_lgamma(SType); // Floating-point umaker_ptr resolve_op_isfinite(SType); umaker_ptr resolve_op_isinf(SType); -umaker_ptr resolve_op_isna(SType); umaker_ptr resolve_op_ceil(SType); umaker_ptr resolve_op_abs(SType); umaker_ptr resolve_op_fabs(SType); diff --git a/src/core/expr/op.h b/src/core/expr/op.h index 6ca51b8f29..24261846fe 100644 --- a/src/core/expr/op.h +++ b/src/core/expr/op.h @@ -130,7 +130,6 @@ enum class Op : size_t { ISCLOSE, // head_func_isclose.cc ISFINITE, // funary/floating.cc ISINF, // funary/floating.cc - ISNA, // funary/floating.cc LDEXP, MODF, RINT, // fumary/floating.cc diff --git a/src/datatable/__init__.py b/src/datatable/__init__.py index 8010f4674a..88499fe70f 100644 --- a/src/datatable/__init__.py +++ b/src/datatable/__init__.py @@ -122,7 +122,6 @@ "int8", "intersect", "iread", - "isna", "join", "last", "log", diff --git a/src/datatable/expr/expr.py b/src/datatable/expr/expr.py index e5a342a689..b41fceff33 100644 --- a/src/datatable/expr/expr.py +++ b/src/datatable/expr/expr.py @@ -112,7 +112,6 @@ class OpCodes(enum.Enum): ISCLOSE = 540 ISFINITE = 541 ISINF = 542 - ISNA = 543 LDEXP = 544 MODF = 545 RINT = 546 diff --git a/src/datatable/expr/math.py b/src/datatable/expr/math.py index d5c57245b3..5dc51289e5 100644 --- a/src/datatable/expr/math.py +++ b/src/datatable/expr/math.py @@ -9,7 +9,7 @@ # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, +# distributed undesrc = [False, True, False, False, True]r the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. diff --git a/src/datatable/math.py b/src/datatable/math.py index 2c5828895c..6bb5109dd9 100644 --- a/src/datatable/math.py +++ b/src/datatable/math.py @@ -48,7 +48,6 @@ isclose, isfinite, isinf, - isna, ldexp, lgamma, log, @@ -72,9 +71,33 @@ trunc, ) +from datatable.lib._datatable import ( + isna +) + +from datatable.lib import core +import math + +__all__ = [ + "isna" +] + e = 2.718281828459045 golden = 1.618033988749895 pi = 3.141592653589793 tau = 6.283185307179586 nan = float('nan') inf = float('inf') + + +def isna(arg): + if (not isinstance(arg, dict) + and (isinstance(arg, core.FExpr) + or (arg and (hasattr(arg, "__getitem__") and isinstance(arg[0], core.FExpr))))): + return core.isna(arg) + if isinstance(arg, dict) and isinstance([*arg.values()][0], core.FExpr): + return core.isna(arg) + try: + return math.isnan(arg) + except TypeError: + return arg is None diff --git a/tests/ijby/test-assign.py b/tests/ijby/test-assign.py index 5f38c33253..f6940707a9 100644 --- a/tests/ijby/test-assign.py +++ b/tests/ijby/test-assign.py @@ -231,7 +231,7 @@ def test_assign_to_sliced_frame(): def test_assign_string_columns(): DT = dt.Frame(A=["One", "two", "three", None, "five"]) - DT[dt.isna(f.A), f.A] = dt.Frame(["FOUR"]) + DT[dt.math.isna(f.A), f.A] = dt.Frame(["FOUR"]) assert_equals(DT, dt.Frame(A=["One", "two", "three", "FOUR", "five"])) diff --git a/tests/math/test-isna.py b/tests/math/test-isna.py index 7b004742bd..db007b890d 100644 --- a/tests/math/test-isna.py +++ b/tests/math/test-isna.py @@ -78,4 +78,4 @@ def test_isna_joined(): @pytest.mark.parametrize("src", all_sources[:-1]) def test_isna_scalar(src): for val in src: - assert dt.math.isna(val) == (val is None or val is math.nan) + assert dt.math.isna(val) == (val is None or (val is math.nan)) diff --git a/tests/munging/test-delete.py b/tests/munging/test-delete.py index 672cbcfec4..bb184597a2 100644 --- a/tests/munging/test-delete.py +++ b/tests/munging/test-delete.py @@ -23,7 +23,8 @@ #------------------------------------------------------------------------------- import datatable as dt import pytest -from datatable import f, g, isna, ltype +from datatable import f, g, ltype +from datatable.math import isna from datatable.internal import frame_integrity_check from tests import assert_equals diff --git a/tests/munging/test-dt-rows.py b/tests/munging/test-dt-rows.py index 80273e21e3..041c3db2f5 100644 --- a/tests/munging/test-dt-rows.py +++ b/tests/munging/test-dt-rows.py @@ -718,7 +718,7 @@ def test_rows_unary_minus(df1): def test_rows_isna(df1): - from datatable import isna + from datatable.math import isna dt1 = df1[isna(f.A), :] frame_integrity_check(dt1) assert dt1.names == df1.names diff --git a/tests/test-import-all.py b/tests/test-import-all.py index 354dba3950..7a03ca7b95 100644 --- a/tests/test-import-all.py +++ b/tests/test-import-all.py @@ -78,7 +78,7 @@ def test_stypes(): def test_ufuncs(): assert dt.abs != abs assert exp - assert isna + assert dt.math.isna assert log assert log10 From 7acfade26f80f214952c69eb230886f4a5813600 Mon Sep 17 00:00:00 2001 From: samukweku Date: Tue, 14 Mar 2023 09:51:46 +1100 Subject: [PATCH 03/53] update docs --- docs/api/math/isna.rst | 2 +- src/core/expr/{ => funary/isna}/fexpr_isna.cc | 4 ++-- src/core/expr/{ => funary/isna}/fexpr_isna.h | 0 3 files changed, 3 insertions(+), 3 deletions(-) rename src/core/expr/{ => funary/isna}/fexpr_isna.cc (97%) rename src/core/expr/{ => funary/isna}/fexpr_isna.h (100%) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index d76c4e4740..6443b4a821 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -1,6 +1,6 @@ .. xfunction:: datatable.math.isna - :src: src/core/expr/fexpr_isna.cc pyfn_isna + :src: src/core/expr/funary/isna/fexpr_isna.cc pyfn_isna :tests: tests/math/test-isna.py :cvar: doc_math_isna :signature: isna(x) diff --git a/src/core/expr/fexpr_isna.cc b/src/core/expr/funary/isna/fexpr_isna.cc similarity index 97% rename from src/core/expr/fexpr_isna.cc rename to src/core/expr/funary/isna/fexpr_isna.cc index dfc08e9597..949372d20c 100644 --- a/src/core/expr/fexpr_isna.cc +++ b/src/core/expr/funary/isna/fexpr_isna.cc @@ -23,7 +23,7 @@ #include "column/const.h" #include "documentation.h" #include "expr/fexpr_column.h" -#include "expr/fexpr_isna.h" +#include "expr/funary/isna/fexpr_isna.h" #include "expr/eval_context.h" #include "expr/workframe.h" #include "python/xargs.h" @@ -81,7 +81,7 @@ static py::oobj pyfn_isna(const py::XArgs& args) { DECLARE_PYFN(&pyfn_isna) ->name("isna") - //->docs(doc_dt_isna) + ->docs(doc_math_isna) ->arg_names({"cols"}) ->n_positional_args(1) ->n_required_args(1); diff --git a/src/core/expr/fexpr_isna.h b/src/core/expr/funary/isna/fexpr_isna.h similarity index 100% rename from src/core/expr/fexpr_isna.h rename to src/core/expr/funary/isna/fexpr_isna.h From d69b35f7db8aad7aeabacad56e4ddf9ee0404fee Mon Sep 17 00:00:00 2001 From: samukweku Date: Tue, 14 Mar 2023 09:55:15 +1100 Subject: [PATCH 04/53] modify docs --- docs/api/math/isna.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 6443b4a821..3307f02bc6 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -14,7 +14,7 @@ return: Expr f-expression having one row, and the same names and number of columns - as in `cols`. All the returned column stypes are `int8`. + as in `cols`. All the returned column stypes are `bool8`. Examples -------- From adfd3512e9bbf1077a82ba049c96242b65a8d81e Mon Sep 17 00:00:00 2001 From: samukweku Date: Tue, 14 Mar 2023 09:59:23 +1100 Subject: [PATCH 05/53] fixes --- src/core/expr/fnary/rowcount.cc | 1 - src/datatable/expr/math.py | 2 +- tests/math/test-isna.py | 2 +- 3 files changed, 2 insertions(+), 3 deletions(-) diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index 6c5d235f1d..a09e5abeb4 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -77,7 +77,6 @@ Column FExpr_RowCount::apply_function(colvec&& columns, for (size_t i = 0; i < columns.size(); ++i) { xassert(columns[i].nrows() == nrows); columns[i] = make_isna_col(std::move(columns[i])); - //columns[i] = unaryop(Op::ISNA, std::move(columns[i])); } return Column(new FuncNary_ColumnImpl( std::move(columns), op_rowcount, nrows, SType::INT32)); diff --git a/src/datatable/expr/math.py b/src/datatable/expr/math.py index 5dc51289e5..d5c57245b3 100644 --- a/src/datatable/expr/math.py +++ b/src/datatable/expr/math.py @@ -9,7 +9,7 @@ # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software -# distributed undesrc = [False, True, False, False, True]r the License is distributed on an "AS IS" BASIS, +# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. diff --git a/tests/math/test-isna.py b/tests/math/test-isna.py index db007b890d..7b004742bd 100644 --- a/tests/math/test-isna.py +++ b/tests/math/test-isna.py @@ -78,4 +78,4 @@ def test_isna_joined(): @pytest.mark.parametrize("src", all_sources[:-1]) def test_isna_scalar(src): for val in src: - assert dt.math.isna(val) == (val is None or (val is math.nan)) + assert dt.math.isna(val) == (val is None or val is math.nan) From 629df725271eff8e098236cf858114b316ad2645 Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 15 Mar 2023 20:38:57 +1100 Subject: [PATCH 06/53] add method for isna --- docs/api/fexpr/isna.rst | 7 +++++++ src/core/documentation.h | 1 + src/core/expr/fexpr.cc | 11 ++++++++++- src/core/expr/fexpr.h | 1 + 4 files changed, 19 insertions(+), 1 deletion(-) create mode 100644 docs/api/fexpr/isna.rst diff --git a/docs/api/fexpr/isna.rst b/docs/api/fexpr/isna.rst new file mode 100644 index 0000000000..136fc5217d --- /dev/null +++ b/docs/api/fexpr/isna.rst @@ -0,0 +1,7 @@ + +.. xmethod:: datatable.FExpr.isna + :src: src/core/expr/fexpr.cc PyFExpr::isna + :cvar: doc_FExpr_isna + :signature: isna(cols) + + Equivalent to :func:`dt.math.isna(cols)`. diff --git a/src/core/documentation.h b/src/core/documentation.h index 2cc4f743ad..b94ebbdb83 100644 --- a/src/core/documentation.h +++ b/src/core/documentation.h @@ -297,6 +297,7 @@ extern const char* doc_FExpr_cumsum; extern const char* doc_FExpr_extend; extern const char* doc_FExpr_fillna; extern const char* doc_FExpr_first; +extern const char* doc_FExpr_isna; extern const char* doc_FExpr_last; extern const char* doc_FExpr_max; extern const char* doc_FExpr_mean; diff --git a/src/core/expr/fexpr.cc b/src/core/expr/fexpr.cc index dfd59391cc..735bc9e4af 100644 --- a/src/core/expr/fexpr.cc +++ b/src/core/expr/fexpr.cc @@ -290,7 +290,6 @@ DECLARE_METHOD(&PyFExpr::re_match) - //------------------------------------------------------------------------------ // Miscellaneous //------------------------------------------------------------------------------ @@ -480,6 +479,16 @@ DECLARE_METHOD(&PyFExpr::first) ->docs(dt::doc_FExpr_first); +oobj PyFExpr::isna(const XArgs&) { + auto isnaFn = oobj::import("datatable", "math", "isna"); + return isnaFn.call({this}); +} + +DECLARE_METHOD(&PyFExpr::isna) + ->name("isna") + ->docs(dt::doc_FExpr_isna); + + oobj PyFExpr::last(const XArgs&) { auto lastFn = oobj::import("datatable", "last"); return lastFn.call({this}); diff --git a/src/core/expr/fexpr.h b/src/core/expr/fexpr.h index b292bbb1d8..decb80acad 100644 --- a/src/core/expr/fexpr.h +++ b/src/core/expr/fexpr.h @@ -192,6 +192,7 @@ class PyFExpr : public py::XObject { py::oobj extend(const py::XArgs&); py::oobj fillna(const py::XArgs&); py::oobj first(const py::XArgs&); + py::oobj isna(const py::XArgs&); py::oobj last(const py::XArgs&); py::oobj max(const py::XArgs&); py::oobj mean(const py::XArgs&); From f34944fde9c12f15c989602bc896dcac661c040f Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 15 Mar 2023 20:53:20 +1100 Subject: [PATCH 07/53] add tests for isna method --- tests/test-f.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test-f.py b/tests/test-f.py index 492e108fac..f86c4be9f6 100644 --- a/tests/test-f.py +++ b/tests/test-f.py @@ -499,3 +499,7 @@ def test_codes(): type = dt.Type.cat8(dt.Type.str32)) assert_equals(DT[:, f.A.codes()], DT[:, dt.codes(f.A)]) +def test_isna(): + assert str(dt.math.isna(f.A)) == str(f.A.isna()) + DT = dt.Frame(A = [None, 9, 8, 2, 3, None, None, 3, 0, 5, 5, 8, None]) + assert_equals (DT[:, dt.math.isna(f.A)], DT[:, f.A.isna()]) \ No newline at end of file From 4c5351c01225aedb4d0bb646f2d1ba10a27796d4 Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 15 Mar 2023 20:56:06 +1100 Subject: [PATCH 08/53] format with clang-format --- src/core/expr/funary/isna/fexpr_isna.cc | 116 +++++++++++++----------- 1 file changed, 65 insertions(+), 51 deletions(-) diff --git a/src/core/expr/funary/isna/fexpr_isna.cc b/src/core/expr/funary/isna/fexpr_isna.cc index 949372d20c..48171b82f1 100644 --- a/src/core/expr/funary/isna/fexpr_isna.cc +++ b/src/core/expr/funary/isna/fexpr_isna.cc @@ -27,63 +27,77 @@ #include "expr/eval_context.h" #include "expr/workframe.h" #include "python/xargs.h" -namespace dt { -namespace expr { +namespace dt +{ + namespace expr + { -FExpr_ISNA::FExpr_ISNA(ptrExpr&& arg) : - arg_(std::move(arg)) - {} + FExpr_ISNA::FExpr_ISNA(ptrExpr &&arg) : arg_(std::move(arg)) + {} + std::string FExpr_ISNA::repr() const + { + std::string out = "isna"; + out += '('; + out += arg_->repr(); + out += ')'; + return out; + } -std::string FExpr_ISNA::repr() const { - std::string out = "isna"; - out += '('; - out += arg_->repr(); - out += ')'; - return out; -} + static Column make_isna_col(Column &&col) + { + switch (col.stype()) + { + case SType::VOID: + return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: + return Column(new Isna_ColumnImpl(std::move(col))); + default: + throw RuntimeError(); + } + } -static Column make_isna_col(Column&& col) { - switch (col.stype()) { - case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::DATE32: - case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::TIME64: - case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); - default: throw RuntimeError(); - } -} - - -Workframe FExpr_ISNA::evaluate_n(EvalContext& ctx) const { - Workframe wf = arg_->evaluate_n(ctx); + Workframe FExpr_ISNA::evaluate_n(EvalContext &ctx) const + { + Workframe wf = arg_->evaluate_n(ctx); - for (size_t i = 0; i < wf.ncols(); ++i) { - Column coli = make_isna_col(wf.retrieve_column(i)); - wf.replace_column(i, std::move(coli)); - } - - return wf; -} + for (size_t i = 0; i < wf.ncols(); ++i) + { + Column coli = make_isna_col(wf.retrieve_column(i)); + wf.replace_column(i, std::move(coli)); + } + return wf; + } -static py::oobj pyfn_isna(const py::XArgs& args) { - auto isna = args[0].to_oobj(); - return PyFExpr::make(new FExpr_ISNA(as_fexpr(isna))); -} + static py::oobj pyfn_isna(const py::XArgs &args) + { + auto isna = args[0].to_oobj(); + return PyFExpr::make(new FExpr_ISNA(as_fexpr(isna))); + } -DECLARE_PYFN(&pyfn_isna) - ->name("isna") - ->docs(doc_math_isna) - ->arg_names({"cols"}) - ->n_positional_args(1) - ->n_required_args(1); + DECLARE_PYFN(&pyfn_isna) + ->name("isna") + ->docs(doc_math_isna) + ->arg_names({"cols"}) + ->n_positional_args(1) + ->n_required_args(1); -}} // dt::expr + } +} // dt::expr From 59fc3f6918731c5f6cbcb8e2c31a1ce81febbd5c Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 15 Mar 2023 21:20:35 +1100 Subject: [PATCH 09/53] indent --- src/core/expr/funary/isna/fexpr_isna.cc | 44 ++++++++++++------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/core/expr/funary/isna/fexpr_isna.cc b/src/core/expr/funary/isna/fexpr_isna.cc index 48171b82f1..1d02a79fdb 100644 --- a/src/core/expr/funary/isna/fexpr_isna.cc +++ b/src/core/expr/funary/isna/fexpr_isna.cc @@ -48,28 +48,28 @@ namespace dt { switch (col.stype()) { - case SType::VOID: - return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::DATE32: - case SType::INT32: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::TIME64: - case SType::INT64: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::STR32: - case SType::STR64: - return Column(new Isna_ColumnImpl(std::move(col))); - default: - throw RuntimeError(); + case SType::VOID: + return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: + return Column(new Isna_ColumnImpl(std::move(col))); + default: + throw RuntimeError(); } } From 18d1f97b88c2fe99dc46a88cfa942c1438648d70 Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 15 Mar 2023 22:15:31 +1100 Subject: [PATCH 10/53] update fexpr_isna --- docs/api/fexpr/isna.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/fexpr/isna.rst b/docs/api/fexpr/isna.rst index 136fc5217d..f2726b05bb 100644 --- a/docs/api/fexpr/isna.rst +++ b/docs/api/fexpr/isna.rst @@ -2,6 +2,6 @@ .. xmethod:: datatable.FExpr.isna :src: src/core/expr/fexpr.cc PyFExpr::isna :cvar: doc_FExpr_isna - :signature: isna(cols) + :signature: isna() Equivalent to :func:`dt.math.isna(cols)`. From d30c22690d32b0f7f2cc363c14f947a908963a91 Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 15 Mar 2023 22:26:07 +1100 Subject: [PATCH 11/53] add to api/fexpr.rst --- docs/api/fexpr.rst | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/api/fexpr.rst b/docs/api/fexpr.rst index da6fe0448a..dc4431a86e 100644 --- a/docs/api/fexpr.rst +++ b/docs/api/fexpr.rst @@ -190,6 +190,9 @@ * - :meth:`.first()` - Same as :func:`dt.first()`. + * - :meth:`.isna()` + - Same as :func:`dt.math.isna()`. + * - :meth:`.last()` - Same as :func:`dt.last()`. @@ -320,6 +323,7 @@ .extend() .fillna() .first() + .isna() .last() .len() .max() From a70445870116c809155149facf1c92e9539ed5ec Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 15 Mar 2023 22:27:56 +1100 Subject: [PATCH 12/53] fix spelling --- docs/api/fexpr.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/fexpr.rst b/docs/api/fexpr.rst index dc4431a86e..7b4c9dc1f7 100644 --- a/docs/api/fexpr.rst +++ b/docs/api/fexpr.rst @@ -63,7 +63,7 @@ - Remove columns from the ``FExpr``. - Arithmeritc operators + Arithmetic operators --------------------- .. list-table:: From 0fcbd6808de24f1292a86c4e5fc695fb38963cfe Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 15 Mar 2023 22:57:04 +1100 Subject: [PATCH 13/53] fix docs failing --- docs/api/fexpr.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/fexpr.rst b/docs/api/fexpr.rst index 7b4c9dc1f7..bee6eb478c 100644 --- a/docs/api/fexpr.rst +++ b/docs/api/fexpr.rst @@ -64,7 +64,7 @@ Arithmetic operators - --------------------- + -------------------- .. list-table:: :widths: auto From ae3ee4be601b4775e6c1279e2fac3dff38c220e6 Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Fri, 24 Mar 2023 07:17:52 +1100 Subject: [PATCH 14/53] Update docs/api/math/isna.rst Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- docs/api/math/isna.rst | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 3307f02bc6..305304d293 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -12,9 +12,8 @@ cols: FExpr Input columns. - return: Expr - f-expression having one row, and the same names and number of columns - as in `cols`. All the returned column stypes are `bool8`. + return: FExpr + f-expression that returns `0` for valid elements and `1` otherwise. All the resulting columns will have `bool8` stypes and as many rows/columns as there are in `cols`. Examples -------- From af6be42e573f6b27bfd8fe617b64640f11a14a6f Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Fri, 24 Mar 2023 07:18:08 +1100 Subject: [PATCH 15/53] Update docs/api/math/isna.rst Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- docs/api/math/isna.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 305304d293..ed7e850ed7 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -3,7 +3,7 @@ :src: src/core/expr/funary/isna/fexpr_isna.cc pyfn_isna :tests: tests/math/test-isna.py :cvar: doc_math_isna - :signature: isna(x) + :signature: isna(cols) Returns `True` if the argument is NA, and `False` otherwise. From ff06759254d95dccecb15a38c8d638a3d900b133 Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Fri, 24 Mar 2023 07:18:30 +1100 Subject: [PATCH 16/53] Update docs/api/math/isna.rst Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- docs/api/math/isna.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index ed7e850ed7..f98a935865 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -5,7 +5,7 @@ :cvar: doc_math_isna :signature: isna(cols) - Returns `True` if the argument is NA, and `False` otherwise. + Tests if the column elements are missing values. Parameters ---------- From adb4cf4718e9007b55defdf69b18bf5f109afbda Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Sat, 25 Mar 2023 18:34:31 +1100 Subject: [PATCH 17/53] Update src/core/expr/funary/isna/fexpr_isna.cc Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- src/core/expr/funary/isna/fexpr_isna.cc | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/core/expr/funary/isna/fexpr_isna.cc b/src/core/expr/funary/isna/fexpr_isna.cc index 1d02a79fdb..e919ed39a8 100644 --- a/src/core/expr/funary/isna/fexpr_isna.cc +++ b/src/core/expr/funary/isna/fexpr_isna.cc @@ -27,10 +27,8 @@ #include "expr/eval_context.h" #include "expr/workframe.h" #include "python/xargs.h" -namespace dt -{ - namespace expr - { +namespace dt { +namespace expr { FExpr_ISNA::FExpr_ISNA(ptrExpr &&arg) : arg_(std::move(arg)) {} From 64b86db35343860b61a123cad4b760d8c9219a83 Mon Sep 17 00:00:00 2001 From: samukweku Date: Sat, 25 Mar 2023 18:34:27 +1100 Subject: [PATCH 18/53] ditch isna folder --- src/core/expr/funary/{isna => }/fexpr_isna.cc | 2 +- src/core/expr/funary/{isna => }/fexpr_isna.h | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename src/core/expr/funary/{isna => }/fexpr_isna.cc (98%) rename src/core/expr/funary/{isna => }/fexpr_isna.h (100%) diff --git a/src/core/expr/funary/isna/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc similarity index 98% rename from src/core/expr/funary/isna/fexpr_isna.cc rename to src/core/expr/funary/fexpr_isna.cc index e919ed39a8..391dfb5ee3 100644 --- a/src/core/expr/funary/isna/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -23,7 +23,7 @@ #include "column/const.h" #include "documentation.h" #include "expr/fexpr_column.h" -#include "expr/funary/isna/fexpr_isna.h" +#include "expr/funary/fexpr_isna.h" #include "expr/eval_context.h" #include "expr/workframe.h" #include "python/xargs.h" diff --git a/src/core/expr/funary/isna/fexpr_isna.h b/src/core/expr/funary/fexpr_isna.h similarity index 100% rename from src/core/expr/funary/isna/fexpr_isna.h rename to src/core/expr/funary/fexpr_isna.h From d95f0c1c74233bbc627462ec88a953c45cec7fb2 Mon Sep 17 00:00:00 2001 From: samukweku Date: Sat, 25 Mar 2023 19:27:10 +1100 Subject: [PATCH 19/53] update fexpr --- docs/api/fexpr.rst | 4 +- docs/api/fexpr/isna.rst | 7 -- docs/api/fexpr/math_isna.rst | 7 ++ docs/api/math/isna.rst | 2 +- src/core/expr/fexpr.cc | 6 +- src/core/expr/fexpr.h | 2 +- src/core/expr/funary/fexpr_isna.cc | 121 ++++++++++++++--------------- src/datatable/math.py | 17 +--- tests/math/test-isna.py | 4 +- tests/test-f.py | 4 +- 10 files changed, 77 insertions(+), 97 deletions(-) delete mode 100644 docs/api/fexpr/isna.rst create mode 100644 docs/api/fexpr/math_isna.rst diff --git a/docs/api/fexpr.rst b/docs/api/fexpr.rst index bee6eb478c..b8a179ca4e 100644 --- a/docs/api/fexpr.rst +++ b/docs/api/fexpr.rst @@ -190,7 +190,7 @@ * - :meth:`.first()` - Same as :func:`dt.first()`. - * - :meth:`.isna()` + * - :meth:`.math_isna()` - Same as :func:`dt.math.isna()`. * - :meth:`.last()` @@ -323,7 +323,7 @@ .extend() .fillna() .first() - .isna() + .math_isna() .last() .len() .max() diff --git a/docs/api/fexpr/isna.rst b/docs/api/fexpr/isna.rst deleted file mode 100644 index f2726b05bb..0000000000 --- a/docs/api/fexpr/isna.rst +++ /dev/null @@ -1,7 +0,0 @@ - -.. xmethod:: datatable.FExpr.isna - :src: src/core/expr/fexpr.cc PyFExpr::isna - :cvar: doc_FExpr_isna - :signature: isna() - - Equivalent to :func:`dt.math.isna(cols)`. diff --git a/docs/api/fexpr/math_isna.rst b/docs/api/fexpr/math_isna.rst new file mode 100644 index 0000000000..a2ddd03e60 --- /dev/null +++ b/docs/api/fexpr/math_isna.rst @@ -0,0 +1,7 @@ + +.. xmethod:: datatable.FExpr.math_isna + :src: src/core/expr/fexpr.cc PyFExpr::math_isna + :cvar: doc_FExpr_isna + :signature: math_isna() + + Equivalent to :func:`dt.math.isna(cols)`. diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index f98a935865..1a7aa2440a 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -1,6 +1,6 @@ .. xfunction:: datatable.math.isna - :src: src/core/expr/funary/isna/fexpr_isna.cc pyfn_isna + :src: src/core/expr/funary/fexpr_isna.cc pyfn_isna :tests: tests/math/test-isna.py :cvar: doc_math_isna :signature: isna(cols) diff --git a/src/core/expr/fexpr.cc b/src/core/expr/fexpr.cc index 735bc9e4af..17a6bb47df 100644 --- a/src/core/expr/fexpr.cc +++ b/src/core/expr/fexpr.cc @@ -479,13 +479,13 @@ DECLARE_METHOD(&PyFExpr::first) ->docs(dt::doc_FExpr_first); -oobj PyFExpr::isna(const XArgs&) { +oobj PyFExpr::math_isna(const XArgs&) { auto isnaFn = oobj::import("datatable", "math", "isna"); return isnaFn.call({this}); } -DECLARE_METHOD(&PyFExpr::isna) - ->name("isna") +DECLARE_METHOD(&PyFExpr::math_isna) + ->name("math_isna") ->docs(dt::doc_FExpr_isna); diff --git a/src/core/expr/fexpr.h b/src/core/expr/fexpr.h index decb80acad..c02c0f05f8 100644 --- a/src/core/expr/fexpr.h +++ b/src/core/expr/fexpr.h @@ -192,7 +192,7 @@ class PyFExpr : public py::XObject { py::oobj extend(const py::XArgs&); py::oobj fillna(const py::XArgs&); py::oobj first(const py::XArgs&); - py::oobj isna(const py::XArgs&); + py::oobj math_isna(const py::XArgs&); py::oobj last(const py::XArgs&); py::oobj max(const py::XArgs&); py::oobj mean(const py::XArgs&); diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc index 391dfb5ee3..19db104165 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -19,83 +19,76 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //------------------------------------------------------------------------------ -#include "column/isna.h" +#include "expr/funary/fexpr_isna.h" #include "column/const.h" +#include "column/isna.h" #include "documentation.h" -#include "expr/fexpr_column.h" -#include "expr/funary/fexpr_isna.h" #include "expr/eval_context.h" +#include "expr/fexpr_column.h" #include "expr/workframe.h" #include "python/xargs.h" namespace dt { namespace expr { - FExpr_ISNA::FExpr_ISNA(ptrExpr &&arg) : arg_(std::move(arg)) - {} +FExpr_ISNA::FExpr_ISNA(ptrExpr &&arg) : arg_(std::move(arg)) {} - std::string FExpr_ISNA::repr() const - { - std::string out = "isna"; - out += '('; - out += arg_->repr(); - out += ')'; - return out; - } +std::string FExpr_ISNA::repr() const { + std::string out = "isna"; + out += '('; + out += arg_->repr(); + out += ')'; + return out; +} - static Column make_isna_col(Column &&col) - { - switch (col.stype()) - { - case SType::VOID: - return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::DATE32: - case SType::INT32: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::TIME64: - case SType::INT64: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::STR32: - case SType::STR64: - return Column(new Isna_ColumnImpl(std::move(col))); - default: - throw RuntimeError(); - } - } +static Column make_isna_col(Column &&col) { + switch (col.stype()) { + case SType::VOID: + return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: + return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: + return Column(new Isna_ColumnImpl(std::move(col))); + default: + throw RuntimeError(); + } +} - Workframe FExpr_ISNA::evaluate_n(EvalContext &ctx) const - { - Workframe wf = arg_->evaluate_n(ctx); +Workframe FExpr_ISNA::evaluate_n(EvalContext &ctx) const { + Workframe wf = arg_->evaluate_n(ctx); - for (size_t i = 0; i < wf.ncols(); ++i) - { - Column coli = make_isna_col(wf.retrieve_column(i)); - wf.replace_column(i, std::move(coli)); - } + for (size_t i = 0; i < wf.ncols(); ++i) { + Column coli = make_isna_col(wf.retrieve_column(i)); + wf.replace_column(i, std::move(coli)); + } - return wf; - } + return wf; +} - static py::oobj pyfn_isna(const py::XArgs &args) - { - auto isna = args[0].to_oobj(); - return PyFExpr::make(new FExpr_ISNA(as_fexpr(isna))); - } +static py::oobj pyfn_isna(const py::XArgs &args) { + auto isna = args[0].to_oobj(); + return PyFExpr::make(new FExpr_ISNA(as_fexpr(isna))); +} - DECLARE_PYFN(&pyfn_isna) - ->name("isna") - ->docs(doc_math_isna) - ->arg_names({"cols"}) - ->n_positional_args(1) - ->n_required_args(1); +DECLARE_PYFN(&pyfn_isna) + ->name("isna") + ->docs(doc_math_isna) + ->arg_names({"cols"}) + ->n_positional_args(1) + ->n_required_args(1); - } -} // dt::expr +} // namespace expr +} // namespace dt diff --git a/src/datatable/math.py b/src/datatable/math.py index 6bb5109dd9..c4660bdad6 100644 --- a/src/datatable/math.py +++ b/src/datatable/math.py @@ -48,6 +48,7 @@ isclose, isfinite, isinf, + isna, ldexp, lgamma, log, @@ -71,10 +72,6 @@ trunc, ) -from datatable.lib._datatable import ( - isna -) - from datatable.lib import core import math @@ -89,15 +86,3 @@ nan = float('nan') inf = float('inf') - -def isna(arg): - if (not isinstance(arg, dict) - and (isinstance(arg, core.FExpr) - or (arg and (hasattr(arg, "__getitem__") and isinstance(arg[0], core.FExpr))))): - return core.isna(arg) - if isinstance(arg, dict) and isinstance([*arg.values()][0], core.FExpr): - return core.isna(arg) - try: - return math.isnan(arg) - except TypeError: - return arg is None diff --git a/tests/math/test-isna.py b/tests/math/test-isna.py index 7b004742bd..744a78d704 100644 --- a/tests/math/test-isna.py +++ b/tests/math/test-isna.py @@ -74,8 +74,10 @@ def test_isna_joined(): dt.internal.frame_integrity_check(RES) assert RES.to_list() == [[True, True, False, True, False]] * 4 - +@pytest.mark.xfail(reason="scalar NA check not supported") @pytest.mark.parametrize("src", all_sources[:-1]) def test_isna_scalar(src): for val in src: assert dt.math.isna(val) == (val is None or val is math.nan) + + diff --git a/tests/test-f.py b/tests/test-f.py index f86c4be9f6..044f7b7f10 100644 --- a/tests/test-f.py +++ b/tests/test-f.py @@ -500,6 +500,6 @@ def test_codes(): assert_equals(DT[:, f.A.codes()], DT[:, dt.codes(f.A)]) def test_isna(): - assert str(dt.math.isna(f.A)) == str(f.A.isna()) + assert str(dt.math.isna(f.A)) == str(f.A.math_isna()) DT = dt.Frame(A = [None, 9, 8, 2, 3, None, None, 3, 0, 5, 5, 8, None]) - assert_equals (DT[:, dt.math.isna(f.A)], DT[:, f.A.isna()]) \ No newline at end of file + assert_equals (DT[:, dt.math.isna(f.A)], DT[:, f.A.math_isna()]) \ No newline at end of file From 0733560810d6b0f8590da4ee32e17051165d5879 Mon Sep 17 00:00:00 2001 From: samukweku Date: Sun, 26 Mar 2023 22:11:18 +1100 Subject: [PATCH 20/53] simplify logic for isna --- src/core/column/isna.h | 10 ++--- src/core/expr/fbinary/fexpr__eq__.cc | 14 +++---- src/core/expr/fexpr_fillna.cc | 42 ++++++++++---------- src/core/expr/fnary/rowcount.cc | 14 +++---- src/core/expr/funary/fexpr_isna.cc | 58 ++++++++++++++-------------- 5 files changed, 70 insertions(+), 68 deletions(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 0328702ee0..74c3573bb7 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -26,7 +26,7 @@ namespace dt { -template +//template class Isna_ColumnImpl : public Virtual_ColumnImpl { protected: Column arg_; @@ -36,12 +36,12 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { : Virtual_ColumnImpl(col.nrows(), SType::BOOL), arg_(std::move(col)) { - xassert(arg_.can_be_read_as()); + //xassert(arg_.can_be_read_as()); } ColumnImpl* clone() const override { - return new Isna_ColumnImpl(Column(arg_)); + return new Isna_ColumnImpl(Column(arg_)); } size_t n_children() const noexcept override { @@ -55,8 +55,8 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { bool get_element(size_t i, int8_t* out) const override { - T tmp; - *out = ! arg_.get_element(i, &tmp); + // T tmp; + *out = !arg_.get_element_isvalid(i); return true; } }; diff --git a/src/core/expr/fbinary/fexpr__eq__.cc b/src/core/expr/fbinary/fexpr__eq__.cc index 08c65b37e4..38255629d9 100644 --- a/src/core/expr/fbinary/fexpr__eq__.cc +++ b/src/core/expr/fbinary/fexpr__eq__.cc @@ -70,16 +70,16 @@ Column FExpr__eq__::evaluate1(Column&& lcol, Column&& rcol) const { switch (type0.stype()) { case SType::VOID: return Const_ColumnImpl::make_bool_column(lcol.nrows(), true); case SType::BOOL: - case SType::INT8: return Column(new Isna_ColumnImpl(std::move(lcol))); - case SType::INT16: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::INT8: + case SType::INT16: case SType::DATE32: - case SType::INT32: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::INT32: case SType::TIME64: - case SType::INT64: return Column(new Isna_ColumnImpl(std::move(lcol))); - case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(lcol))); - case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::INT64: + case SType::FLOAT32: + case SType::FLOAT64: case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(lcol))); default: break; } } else { diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index 5594c6f690..e81c757ad5 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -19,7 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //------------------------------------------------------------------------------ -#include "column/const.h" +//#include "column/const.h" #include "column/ifelse.h" #include "column/isna.h" #include "column/latent.h" @@ -139,7 +139,7 @@ class FExpr_FillNA : public FExpr_Func { for (size_t i = 0; i < wf.ncols(); ++i) { Column col_orig = Column(wf.get_column(i)); - Column col_cond = make_isna_col(wf.retrieve_column(i)); + Column col_cond = Column(new Isna_ColumnImpl(wf.retrieve_column(i))); Column col_repl = wf_value.retrieve_column(i); SType st = common_stype(col_orig.stype(), col_repl.stype()); @@ -185,25 +185,25 @@ class FExpr_FillNA : public FExpr_Func { } - static Column make_isna_col(Column&& col) { - switch (col.stype()) { - case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::DATE32: - case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::TIME64: - case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); - default: throw RuntimeError(); - } - } - -}; +// static Column make_isna_col(Column&& col) { +// switch (col.stype()) { +// case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); +// case SType::BOOL: +// case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::DATE32: +// case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::TIME64: +// case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::STR32: +// case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); +// default: throw RuntimeError(); +// } +// } + + }; static py::oobj pyfn_fillna(const py::XArgs &args) { diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index a09e5abeb4..c6efa0a65b 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -53,16 +53,16 @@ static Column make_isna_col(Column&& col) { switch (col.stype()) { case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); case SType::BOOL: - case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT8: + case SType::INT16: case SType::DATE32: - case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT32: case SType::TIME64: - case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT64: + case SType::FLOAT32: + case SType::FLOAT64: case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); default: throw RuntimeError(); } } diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc index 19db104165..067a50b047 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -30,7 +30,9 @@ namespace dt { namespace expr { -FExpr_ISNA::FExpr_ISNA(ptrExpr &&arg) : arg_(std::move(arg)) {} +FExpr_ISNA::FExpr_ISNA(ptrExpr &&arg) + : arg_(std::move(arg)) + {} std::string FExpr_ISNA::repr() const { std::string out = "isna"; @@ -40,38 +42,38 @@ std::string FExpr_ISNA::repr() const { return out; } -static Column make_isna_col(Column &&col) { - switch (col.stype()) { - case SType::VOID: - return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::DATE32: - case SType::INT32: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::TIME64: - case SType::INT64: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: - return Column(new Isna_ColumnImpl(std::move(col))); - case SType::STR32: - case SType::STR64: - return Column(new Isna_ColumnImpl(std::move(col))); - default: - throw RuntimeError(); - } -} +// static Column make_isna_col(Column &&col) { +// switch (col.stype()) { +// case SType::VOID: +// return Const_ColumnImpl::make_bool_column(col.nrows(), true); +// case SType::BOOL: +// case SType::INT8: +// return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::INT16: +// return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::DATE32: +// case SType::INT32: +// return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::TIME64: +// case SType::INT64: +// return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::FLOAT32: +// return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::FLOAT64: +// return Column(new Isna_ColumnImpl(std::move(col))); +// case SType::STR32: +// case SType::STR64: +// return Column(new Isna_ColumnImpl(std::move(col))); +// default: +// throw RuntimeError(); +// } +// } Workframe FExpr_ISNA::evaluate_n(EvalContext &ctx) const { Workframe wf = arg_->evaluate_n(ctx); for (size_t i = 0; i < wf.ncols(); ++i) { - Column coli = make_isna_col(wf.retrieve_column(i)); + Column coli = Column(new Isna_ColumnImpl(wf.retrieve_column(i))); wf.replace_column(i, std::move(coli)); } From 80b687faebf8edeb5a727805d58a4faf89abe2a1 Mon Sep 17 00:00:00 2001 From: samukweku Date: Sun, 26 Mar 2023 23:00:31 +1100 Subject: [PATCH 21/53] further simplify isna logic --- src/core/expr/fbinary/fexpr__eq__.cc | 17 ++++--------- src/core/expr/fnary/rowcount.cc | 23 ++++-------------- src/core/expr/funary/fexpr_isna.cc | 36 ++++++---------------------- 3 files changed, 15 insertions(+), 61 deletions(-) diff --git a/src/core/expr/fbinary/fexpr__eq__.cc b/src/core/expr/fbinary/fexpr__eq__.cc index 38255629d9..d7aaa9c966 100644 --- a/src/core/expr/fbinary/fexpr__eq__.cc +++ b/src/core/expr/fbinary/fexpr__eq__.cc @@ -68,19 +68,10 @@ Column FExpr__eq__::evaluate1(Column&& lcol, Column&& rcol) const { std::swap(lcol, rcol); } switch (type0.stype()) { - case SType::VOID: return Const_ColumnImpl::make_bool_column(lcol.nrows(), true); - case SType::BOOL: - case SType::INT8: - case SType::INT16: - case SType::DATE32: - case SType::INT32: - case SType::TIME64: - case SType::INT64: - case SType::FLOAT32: - case SType::FLOAT64: - case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(lcol))); - default: break; + case SType::VOID: + return Const_ColumnImpl::make_bool_column(lcol.nrows(), true); + default: + return Column(new Isna_ColumnImpl(std::move(lcol))); } } else { switch (type0.stype()) { diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index c6efa0a65b..d8757e84d0 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -49,24 +49,6 @@ static bool op_rowcount(size_t i, int32_t* out, const colvec& columns) { return true; } -static Column make_isna_col(Column&& col) { - switch (col.stype()) { - case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: - case SType::INT16: - case SType::DATE32: - case SType::INT32: - case SType::TIME64: - case SType::INT64: - case SType::FLOAT32: - case SType::FLOAT64: - case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); - default: throw RuntimeError(); - } -} - Column FExpr_RowCount::apply_function(colvec&& columns, const size_t nrows, const size_t) const @@ -76,7 +58,10 @@ Column FExpr_RowCount::apply_function(colvec&& columns, } for (size_t i = 0; i < columns.size(); ++i) { xassert(columns[i].nrows() == nrows); - columns[i] = make_isna_col(std::move(columns[i])); + if (columns[i].stype() == SType::VOID) { + columns[i] = Const_ColumnImpl::make_bool_column(columns[i].nrows(), true); + } + columns[i] = Column(new Isna_ColumnImpl(std::move(columns[i]))); } return Column(new FuncNary_ColumnImpl( std::move(columns), op_rowcount, nrows, SType::INT32)); diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc index 067a50b047..b09498481d 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -42,39 +42,17 @@ std::string FExpr_ISNA::repr() const { return out; } -// static Column make_isna_col(Column &&col) { -// switch (col.stype()) { -// case SType::VOID: -// return Const_ColumnImpl::make_bool_column(col.nrows(), true); -// case SType::BOOL: -// case SType::INT8: -// return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::INT16: -// return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::DATE32: -// case SType::INT32: -// return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::TIME64: -// case SType::INT64: -// return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::FLOAT32: -// return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::FLOAT64: -// return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::STR32: -// case SType::STR64: -// return Column(new Isna_ColumnImpl(std::move(col))); -// default: -// throw RuntimeError(); -// } -// } - Workframe FExpr_ISNA::evaluate_n(EvalContext &ctx) const { Workframe wf = arg_->evaluate_n(ctx); for (size_t i = 0; i < wf.ncols(); ++i) { - Column coli = Column(new Isna_ColumnImpl(wf.retrieve_column(i))); - wf.replace_column(i, std::move(coli)); + Column coli = wf.retrieve_column(i); + if (coli.stype() == SType::VOID) { + coli = Const_ColumnImpl::make_bool_column(coli.nrows(), true); + } else { + coli = Column(new Isna_ColumnImpl(std::move(coli))); + } + wf.replace_column(i, std::move(coli)); } return wf; From d87df85da627ec6daf1b59f846d323848cf17b1f Mon Sep 17 00:00:00 2001 From: samukweku Date: Sun, 26 Mar 2023 23:32:53 +1100 Subject: [PATCH 22/53] cleanup fillna.cc --- src/core/expr/fexpr_fillna.cc | 21 --------------------- 1 file changed, 21 deletions(-) diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index e81c757ad5..2042f2049c 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -19,7 +19,6 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //------------------------------------------------------------------------------ -//#include "column/const.h" #include "column/ifelse.h" #include "column/isna.h" #include "column/latent.h" @@ -183,26 +182,6 @@ class FExpr_FillNA : public FExpr_Func { return wf; } - - -// static Column make_isna_col(Column&& col) { -// switch (col.stype()) { -// case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); -// case SType::BOOL: -// case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::DATE32: -// case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::TIME64: -// case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); -// case SType::STR32: -// case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); -// default: throw RuntimeError(); -// } -// } - }; From 7a382b809b7205e976c58a4c2b0c2ad122cc30cd Mon Sep 17 00:00:00 2001 From: samukweku Date: Mon, 27 Mar 2023 09:20:41 +1100 Subject: [PATCH 23/53] use ternary operator where possible --- src/core/column/isna.h | 10 +++------- src/core/expr/fexpr_fillna.cc | 6 +++++- src/core/expr/fnary/rowcount.cc | 7 +++---- src/core/expr/funary/fexpr_isna.cc | 8 +++----- 4 files changed, 14 insertions(+), 17 deletions(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 74c3573bb7..5067bd9698 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -26,7 +26,6 @@ namespace dt { -//template class Isna_ColumnImpl : public Virtual_ColumnImpl { protected: Column arg_; @@ -35,9 +34,7 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { Isna_ColumnImpl(Column&& col) : Virtual_ColumnImpl(col.nrows(), SType::BOOL), arg_(std::move(col)) - { - //xassert(arg_.can_be_read_as()); - } + {} ColumnImpl* clone() const override { @@ -55,14 +52,13 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { bool get_element(size_t i, int8_t* out) const override { - // T tmp; *out = !arg_.get_element_isvalid(i); return true; } }; - - } // namespace dt #endif + + diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index 2042f2049c..220ac6e7a8 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -19,6 +19,7 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //------------------------------------------------------------------------------ +#include "column/const.h" #include "column/ifelse.h" #include "column/isna.h" #include "column/latent.h" @@ -138,7 +139,10 @@ class FExpr_FillNA : public FExpr_Func { for (size_t i = 0; i < wf.ncols(); ++i) { Column col_orig = Column(wf.get_column(i)); - Column col_cond = Column(new Isna_ColumnImpl(wf.retrieve_column(i))); + Column col_cond = wf.retrieve_column(i); + bool is_void_column = col_cond.stype() == SType::VOID; + col_cond = is_void_column? Const_ColumnImpl::make_bool_column(col_cond.nrows(), true) + : Column(new Isna_ColumnImpl(std::move(col_cond))); Column col_repl = wf_value.retrieve_column(i); SType st = common_stype(col_orig.stype(), col_repl.stype()); diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index d8757e84d0..5383726b10 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -58,10 +58,9 @@ Column FExpr_RowCount::apply_function(colvec&& columns, } for (size_t i = 0; i < columns.size(); ++i) { xassert(columns[i].nrows() == nrows); - if (columns[i].stype() == SType::VOID) { - columns[i] = Const_ColumnImpl::make_bool_column(columns[i].nrows(), true); - } - columns[i] = Column(new Isna_ColumnImpl(std::move(columns[i]))); + bool is_void_column = columns[i].stype() == SType::VOID; + columns[i] = is_void_column? Const_ColumnImpl::make_bool_column(columns[i].nrows(), true) + : Column(new Isna_ColumnImpl(std::move(columns[i]))); } return Column(new FuncNary_ColumnImpl( std::move(columns), op_rowcount, nrows, SType::INT32)); diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc index b09498481d..66e9c48392 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -47,11 +47,9 @@ Workframe FExpr_ISNA::evaluate_n(EvalContext &ctx) const { for (size_t i = 0; i < wf.ncols(); ++i) { Column coli = wf.retrieve_column(i); - if (coli.stype() == SType::VOID) { - coli = Const_ColumnImpl::make_bool_column(coli.nrows(), true); - } else { - coli = Column(new Isna_ColumnImpl(std::move(coli))); - } + bool is_void_column = coli.stype() == SType::VOID; + coli = is_void_column? Const_ColumnImpl::make_bool_column(coli.nrows(), true) + : Column(new Isna_ColumnImpl(std::move(coli))); wf.replace_column(i, std::move(coli)); } From 781c2c38fca095ae700576fff36d689ed97806c0 Mon Sep 17 00:00:00 2001 From: samukweku Date: Mon, 27 Mar 2023 09:26:37 +1100 Subject: [PATCH 24/53] fix indent --- src/core/expr/fexpr_fillna.cc | 7 +++---- src/core/expr/fnary/rowcount.cc | 7 ++++--- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index 220ac6e7a8..fba1be1177 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -55,9 +55,9 @@ class FExpr_FillNA : public FExpr_Func { out +=", value="; out += value_->repr(); } else { - out += ", reverse="; - out += reverse_? "True" : "False"; - } + out += ", reverse="; + out += reverse_? "True" : "False"; + } out += ')'; return out; } @@ -109,7 +109,6 @@ class FExpr_FillNA : public FExpr_Func { fill_id = is_valid? i : fill_id; indices[i] = static_cast(fill_id); } - } } ); diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index 5383726b10..c9266081b7 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -58,9 +58,10 @@ Column FExpr_RowCount::apply_function(colvec&& columns, } for (size_t i = 0; i < columns.size(); ++i) { xassert(columns[i].nrows() == nrows); - bool is_void_column = columns[i].stype() == SType::VOID; - columns[i] = is_void_column? Const_ColumnImpl::make_bool_column(columns[i].nrows(), true) - : Column(new Isna_ColumnImpl(std::move(columns[i]))); + Column coli = columns[i]; + bool is_void_column = coli.stype() == SType::VOID; + columns[i] = is_void_column? Const_ColumnImpl::make_bool_column(coli.nrows(), true) + : Column(new Isna_ColumnImpl(std::move(coli))); } return Column(new FuncNary_ColumnImpl( std::move(columns), op_rowcount, nrows, SType::INT32)); From 9037d0b6a3e4d3a8820ed0a23d665f08f86457ea Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 29 Mar 2023 17:12:28 +1100 Subject: [PATCH 25/53] use FExpr_FuncUnary for isna --- src/core/expr/funary/fexpr_isna.cc | 47 +++++++++++++----------------- src/core/expr/funary/fexpr_isna.h | 41 -------------------------- 2 files changed, 21 insertions(+), 67 deletions(-) delete mode 100644 src/core/expr/funary/fexpr_isna.h diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc index 66e9c48392..a57c400029 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright 2023 H2O.ai +// Copyright 2022-2023 H2O.ai // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), @@ -19,42 +19,37 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS // IN THE SOFTWARE. //------------------------------------------------------------------------------ -#include "expr/funary/fexpr_isna.h" #include "column/const.h" #include "column/isna.h" +#include "expr/fexpr_column.h" #include "documentation.h" +#include "expr/fexpr_func_unary.h" #include "expr/eval_context.h" -#include "expr/fexpr_column.h" #include "expr/workframe.h" #include "python/xargs.h" +#include "stype.h" namespace dt { namespace expr { -FExpr_ISNA::FExpr_ISNA(ptrExpr &&arg) - : arg_(std::move(arg)) - {} -std::string FExpr_ISNA::repr() const { - std::string out = "isna"; - out += '('; - out += arg_->repr(); - out += ')'; - return out; -} +class FExpr_ISNA : public FExpr_FuncUnary { + public: + using FExpr_FuncUnary::FExpr_FuncUnary; -Workframe FExpr_ISNA::evaluate_n(EvalContext &ctx) const { - Workframe wf = arg_->evaluate_n(ctx); - for (size_t i = 0; i < wf.ncols(); ++i) { - Column coli = wf.retrieve_column(i); - bool is_void_column = coli.stype() == SType::VOID; - coli = is_void_column? Const_ColumnImpl::make_bool_column(coli.nrows(), true) - : Column(new Isna_ColumnImpl(std::move(coli))); - wf.replace_column(i, std::move(coli)); - } + std::string name() const override { + return "isna"; + } + + + Column evaluate1(Column&& col) const override{ + bool is_void_column = col.stype() == SType::VOID; + col = is_void_column? Const_ColumnImpl::make_bool_column(col.nrows(), true) + : Column(new Isna_ColumnImpl(std::move(col))); + return std::move(col); + } +}; - return wf; -} static py::oobj pyfn_isna(const py::XArgs &args) { auto isna = args[0].to_oobj(); @@ -68,5 +63,5 @@ DECLARE_PYFN(&pyfn_isna) ->n_positional_args(1) ->n_required_args(1); -} // namespace expr -} // namespace dt + +}} // dt::expr diff --git a/src/core/expr/funary/fexpr_isna.h b/src/core/expr/funary/fexpr_isna.h deleted file mode 100644 index 295758edc2..0000000000 --- a/src/core/expr/funary/fexpr_isna.h +++ /dev/null @@ -1,41 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright 2023 H2O.ai -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//------------------------------------------------------------------------------ -#ifndef dt_EXPR_FEXPR_ISNA_h -#define dt_EXPR_FEXPR_ISNA_h -#include "expr/fexpr_func.h" -namespace dt { -namespace expr { - - -class FExpr_ISNA : public FExpr_Func { - private: - ptrExpr arg_; - - public: - FExpr_ISNA(ptrExpr&& arg); - std::string repr() const override; - Workframe evaluate_n(EvalContext& ctx) const override; -}; - - -}} // dt::expr -#endif From 8704c5076589f4ab7c2c1fa163d429d6583e0719 Mon Sep 17 00:00:00 2001 From: samukweku Date: Tue, 18 Apr 2023 09:28:14 +1000 Subject: [PATCH 26/53] updates based on feedback --- docs/api/math/isna.rst | 4 +++- src/core/expr/fbinary/fexpr__eq__.cc | 14 ++++---------- tests/test-f.py | 3 ++- 3 files changed, 9 insertions(+), 12 deletions(-) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 1a7aa2440a..7da627ec86 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -13,7 +13,9 @@ Input columns. return: FExpr - f-expression that returns `0` for valid elements and `1` otherwise. All the resulting columns will have `bool8` stypes and as many rows/columns as there are in `cols`. + f-expression that returns `0` for valid elements and `1` otherwise. + All the resulting columns will have `bool8` stypes + and as many rows/columns as there are in `cols`. Examples -------- diff --git a/src/core/expr/fbinary/fexpr__eq__.cc b/src/core/expr/fbinary/fexpr__eq__.cc index d7aaa9c966..9ce31f8e9a 100644 --- a/src/core/expr/fbinary/fexpr__eq__.cc +++ b/src/core/expr/fbinary/fexpr__eq__.cc @@ -67,12 +67,9 @@ Column FExpr__eq__::evaluate1(Column&& lcol, Column&& rcol) const { if (type1.is_void()) { std::swap(lcol, rcol); } - switch (type0.stype()) { - case SType::VOID: - return Const_ColumnImpl::make_bool_column(lcol.nrows(), true); - default: - return Column(new Isna_ColumnImpl(std::move(lcol))); - } + if (type0.stype() == SType::VOID) { + return Const_ColumnImpl::make_bool_column(lcol.nrows(), true); + } else return Column(new Isna_ColumnImpl(std::move(lcol))); } else { switch (type0.stype()) { case SType::BOOL: @@ -93,9 +90,6 @@ Column FExpr__eq__::evaluate1(Column&& lcol, Column&& rcol) const { "types `" << type1 << "` and `" << type2 << "`"; } +}} // namespace dt::expr - - - -}} // namespace dt::expr diff --git a/tests/test-f.py b/tests/test-f.py index 044f7b7f10..8e17bcf79a 100644 --- a/tests/test-f.py +++ b/tests/test-f.py @@ -502,4 +502,5 @@ def test_codes(): def test_isna(): assert str(dt.math.isna(f.A)) == str(f.A.math_isna()) DT = dt.Frame(A = [None, 9, 8, 2, 3, None, None, 3, 0, 5, 5, 8, None]) - assert_equals (DT[:, dt.math.isna(f.A)], DT[:, f.A.math_isna()]) \ No newline at end of file + assert_equals (DT[:, dt.math.isna(f.A)], DT[:, f.A.math_isna()]) + From 890e56d118be143b2c7e1a26827d8cf67dcd4232 Mon Sep 17 00:00:00 2001 From: samukweku Date: Sat, 22 Apr 2023 00:47:48 +1000 Subject: [PATCH 27/53] fix test fails --- src/core/column/isna.h | 2 +- src/core/expr/fexpr_fillna.cc | 10 +++++----- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 5067bd9698..5c11883ac6 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -52,7 +52,7 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { bool get_element(size_t i, int8_t* out) const override { - *out = !arg_.get_element_isvalid(i); + *out = !arg_.get_element_validity(i); return true; } }; diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index fba1be1177..1f4845e960 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -104,12 +104,12 @@ class FExpr_FillNA : public FExpr_Func { indices[i] = static_cast(fill_id); } } else { - for (size_t i = i1; i < i2; ++i) { - is_valid = col.get_element(i, &value); - fill_id = is_valid? i : fill_id; - indices[i] = static_cast(fill_id); + for (size_t i = i1; i < i2; ++i) { + is_valid = col.get_element(i, &value); + fill_id = is_valid? i : fill_id; + indices[i] = static_cast(fill_id); + } } - } ); From 2a439599672ad523a2e7af7b5ca9debe6b528059 Mon Sep 17 00:00:00 2001 From: samukweku Date: Sat, 22 Apr 2023 22:36:09 +1000 Subject: [PATCH 28/53] updates based on feedback --- src/core/column/isna.h | 14 ++++++--- src/core/expr/fbinary/fexpr__eq__.cc | 23 +++++++++++--- src/core/expr/fexpr_fillna.cc | 46 +++++++++++++++++++--------- src/core/expr/fnary/rowcount.cc | 21 ++++++++++++- src/core/expr/funary/fexpr_isna.cc | 19 +++++++++++- 5 files changed, 98 insertions(+), 25 deletions(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 5c11883ac6..815b409ef0 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -26,6 +26,7 @@ namespace dt { +template class Isna_ColumnImpl : public Virtual_ColumnImpl { protected: Column arg_; @@ -34,11 +35,13 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { Isna_ColumnImpl(Column&& col) : Virtual_ColumnImpl(col.nrows(), SType::BOOL), arg_(std::move(col)) - {} + { + xassert(arg_.can_be_read_as()); + } ColumnImpl* clone() const override { - return new Isna_ColumnImpl(Column(arg_)); + return new Isna_ColumnImpl(Column(arg_)); } size_t n_children() const noexcept override { @@ -52,13 +55,14 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { bool get_element(size_t i, int8_t* out) const override { - *out = !arg_.get_element_validity(i); + T tmp; + *out = ! arg_.get_element(i, &tmp); return true; } }; -} // namespace dt -#endif +} // namespace dt +#endif \ No newline at end of file diff --git a/src/core/expr/fbinary/fexpr__eq__.cc b/src/core/expr/fbinary/fexpr__eq__.cc index 9ce31f8e9a..08c65b37e4 100644 --- a/src/core/expr/fbinary/fexpr__eq__.cc +++ b/src/core/expr/fbinary/fexpr__eq__.cc @@ -67,9 +67,21 @@ Column FExpr__eq__::evaluate1(Column&& lcol, Column&& rcol) const { if (type1.is_void()) { std::swap(lcol, rcol); } - if (type0.stype() == SType::VOID) { - return Const_ColumnImpl::make_bool_column(lcol.nrows(), true); - } else return Column(new Isna_ColumnImpl(std::move(lcol))); + switch (type0.stype()) { + case SType::VOID: return Const_ColumnImpl::make_bool_column(lcol.nrows(), true); + case SType::BOOL: + case SType::INT8: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::INT16: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::DATE32: + case SType::INT32: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::TIME64: + case SType::INT64: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(lcol))); + case SType::STR32: + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(lcol))); + default: break; + } } else { switch (type0.stype()) { case SType::BOOL: @@ -90,6 +102,9 @@ Column FExpr__eq__::evaluate1(Column&& lcol, Column&& rcol) const { "types `" << type1 << "` and `" << type2 << "`"; } -}} // namespace dt::expr + + + +}} // namespace dt::expr diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index 1f4845e960..bae509c464 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -55,9 +55,9 @@ class FExpr_FillNA : public FExpr_Func { out +=", value="; out += value_->repr(); } else { - out += ", reverse="; - out += reverse_? "True" : "False"; - } + out += ", reverse="; + out += reverse_? "True" : "False"; + } out += ')'; return out; } @@ -104,12 +104,13 @@ class FExpr_FillNA : public FExpr_Func { indices[i] = static_cast(fill_id); } } else { - for (size_t i = i1; i < i2; ++i) { - is_valid = col.get_element(i, &value); - fill_id = is_valid? i : fill_id; - indices[i] = static_cast(fill_id); - } + for (size_t i = i1; i < i2; ++i) { + is_valid = col.get_element(i, &value); + fill_id = is_valid? i : fill_id; + indices[i] = static_cast(fill_id); } + } + } ); @@ -138,10 +139,7 @@ class FExpr_FillNA : public FExpr_Func { for (size_t i = 0; i < wf.ncols(); ++i) { Column col_orig = Column(wf.get_column(i)); - Column col_cond = wf.retrieve_column(i); - bool is_void_column = col_cond.stype() == SType::VOID; - col_cond = is_void_column? Const_ColumnImpl::make_bool_column(col_cond.nrows(), true) - : Column(new Isna_ColumnImpl(std::move(col_cond))); + Column col_cond = make_isna_col(wf.retrieve_column(i)); Column col_repl = wf_value.retrieve_column(i); SType st = common_stype(col_orig.stype(), col_repl.stype()); @@ -185,7 +183,27 @@ class FExpr_FillNA : public FExpr_Func { return wf; } - }; + + + static Column make_isna_col(Column&& col) { + switch (col.stype()) { + case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); + default: throw RuntimeError(); + } + } + +}; static py::oobj pyfn_fillna(const py::XArgs &args) { @@ -217,4 +235,4 @@ DECLARE_PYFN(&pyfn_fillna) ->n_keyword_args(2); -}} // dt::expr +}} // dt::expr \ No newline at end of file diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index c9266081b7..99e4bf91e2 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -49,6 +49,25 @@ static bool op_rowcount(size_t i, int32_t* out, const colvec& columns) { return true; } +static Column make_isna_col(Column&& col) { + switch (col.stype()) { + case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); + default: throw RuntimeError(); + } +} + + Column FExpr_RowCount::apply_function(colvec&& columns, const size_t nrows, const size_t) const @@ -61,7 +80,7 @@ Column FExpr_RowCount::apply_function(colvec&& columns, Column coli = columns[i]; bool is_void_column = coli.stype() == SType::VOID; columns[i] = is_void_column? Const_ColumnImpl::make_bool_column(coli.nrows(), true) - : Column(new Isna_ColumnImpl(std::move(coli))); + : make_isna_col(std::move(coli)); } return Column(new FuncNary_ColumnImpl( std::move(columns), op_rowcount, nrows, SType::INT32)); diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc index a57c400029..fe8e2cc79f 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -41,11 +41,28 @@ class FExpr_ISNA : public FExpr_FuncUnary { return "isna"; } + static Column make_isna_col(Column&& col) { + switch (col.stype()) { + case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); + default: throw RuntimeError(); + } + } Column evaluate1(Column&& col) const override{ bool is_void_column = col.stype() == SType::VOID; col = is_void_column? Const_ColumnImpl::make_bool_column(col.nrows(), true) - : Column(new Isna_ColumnImpl(std::move(col))); + : make_isna_col(std::move(col)); return std::move(col); } }; From b58e93008da836ced1e572880f014644d981233f Mon Sep 17 00:00:00 2001 From: samukweku Date: Mon, 24 Apr 2023 13:36:46 +1000 Subject: [PATCH 29/53] restore newline --- src/core/column/isna.h | 3 ++- src/core/expr/fexpr_fillna.cc | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 815b409ef0..027433483c 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -65,4 +65,5 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { } // namespace dt -#endif \ No newline at end of file +#endif + diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index bae509c464..0924b4cc2d 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -235,4 +235,5 @@ DECLARE_PYFN(&pyfn_fillna) ->n_keyword_args(2); -}} // dt::expr \ No newline at end of file +}} // dt::expr + From 4c90f413fcecced3aed70c9cce56783ae47f0477 Mon Sep 17 00:00:00 2001 From: samukweku Date: Mon, 24 Apr 2023 22:36:48 +1000 Subject: [PATCH 30/53] updates --- src/core/expr/fnary/rowcount.cc | 4 +--- src/core/expr/funary/fexpr_isna.cc | 5 +---- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index 99e4bf91e2..a1cee0ca84 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -78,9 +78,7 @@ Column FExpr_RowCount::apply_function(colvec&& columns, for (size_t i = 0; i < columns.size(); ++i) { xassert(columns[i].nrows() == nrows); Column coli = columns[i]; - bool is_void_column = coli.stype() == SType::VOID; - columns[i] = is_void_column? Const_ColumnImpl::make_bool_column(coli.nrows(), true) - : make_isna_col(std::move(coli)); + columns[i] = make_isna_col(std::move(coli)); } return Column(new FuncNary_ColumnImpl( std::move(columns), op_rowcount, nrows, SType::INT32)); diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc index fe8e2cc79f..e05b7b8721 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -60,10 +60,7 @@ class FExpr_ISNA : public FExpr_FuncUnary { } Column evaluate1(Column&& col) const override{ - bool is_void_column = col.stype() == SType::VOID; - col = is_void_column? Const_ColumnImpl::make_bool_column(col.nrows(), true) - : make_isna_col(std::move(col)); - return std::move(col); + return make_isna_col(std::move(col)); } }; From 8e78f88aa7009e6a5cda0f6ac3fafe61df7a882c Mon Sep 17 00:00:00 2001 From: samukweku Date: Tue, 25 Apr 2023 20:14:50 +1000 Subject: [PATCH 31/53] move make_isna_col to isna.h --- src/core/column/isna.h | 19 ++++++++++++++++++- src/core/expr/fnary/rowcount.cc | 19 ------------------- src/core/expr/funary/fexpr_isna.cc | 18 ------------------ 3 files changed, 18 insertions(+), 38 deletions(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 027433483c..52b87527c2 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -21,6 +21,7 @@ //------------------------------------------------------------------------------ #ifndef dt_COLUMN_ISNA_h #define dt_COLUMN_ISNA_h +#include "column/const.h" #include "column/virtual.h" #include "stype.h" namespace dt { @@ -62,7 +63,23 @@ class Isna_ColumnImpl : public Virtual_ColumnImpl { }; - +static Column make_isna_col(Column&& col) { + switch (col.stype()) { + case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); + case SType::BOOL: + case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::DATE32: + case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::TIME64: + case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); + case SType::STR32: + case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); + default: throw RuntimeError(); + } +} } // namespace dt #endif diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index a1cee0ca84..7b0422e757 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -49,25 +49,6 @@ static bool op_rowcount(size_t i, int32_t* out, const colvec& columns) { return true; } -static Column make_isna_col(Column&& col) { - switch (col.stype()) { - case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::DATE32: - case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::TIME64: - case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); - default: throw RuntimeError(); - } -} - - Column FExpr_RowCount::apply_function(colvec&& columns, const size_t nrows, const size_t) const diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/funary/fexpr_isna.cc index e05b7b8721..fa67f3f8c1 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/funary/fexpr_isna.cc @@ -41,24 +41,6 @@ class FExpr_ISNA : public FExpr_FuncUnary { return "isna"; } - static Column make_isna_col(Column&& col) { - switch (col.stype()) { - case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::DATE32: - case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::TIME64: - case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); - default: throw RuntimeError(); - } - } - Column evaluate1(Column&& col) const override{ return make_isna_col(std::move(col)); } From ef1a9cb670865f6d68e8e812b45320c3ba3a5869 Mon Sep 17 00:00:00 2001 From: samukweku Date: Fri, 28 Apr 2023 19:28:34 +1000 Subject: [PATCH 32/53] update based on feedback --- docs/api/fexpr.rst | 4 ++-- docs/api/fexpr/isna.rst | 7 +++++++ docs/api/fexpr/math_isna.rst | 7 ------- docs/api/math/isna.rst | 9 +++++++++ src/core/expr/fexpr.cc | 6 +++--- src/core/expr/fexpr.h | 2 +- src/core/expr/fexpr_fillna.cc | 20 -------------------- src/core/expr/funary/floating.cc | 1 - src/datatable/__init__.py | 4 +++- tests/math/test-isna.py | 2 +- tests/test-f.py | 4 ++-- 11 files changed, 28 insertions(+), 38 deletions(-) create mode 100644 docs/api/fexpr/isna.rst delete mode 100644 docs/api/fexpr/math_isna.rst diff --git a/docs/api/fexpr.rst b/docs/api/fexpr.rst index b8a179ca4e..bee6eb478c 100644 --- a/docs/api/fexpr.rst +++ b/docs/api/fexpr.rst @@ -190,7 +190,7 @@ * - :meth:`.first()` - Same as :func:`dt.first()`. - * - :meth:`.math_isna()` + * - :meth:`.isna()` - Same as :func:`dt.math.isna()`. * - :meth:`.last()` @@ -323,7 +323,7 @@ .extend() .fillna() .first() - .math_isna() + .isna() .last() .len() .max() diff --git a/docs/api/fexpr/isna.rst b/docs/api/fexpr/isna.rst new file mode 100644 index 0000000000..b80ae238f4 --- /dev/null +++ b/docs/api/fexpr/isna.rst @@ -0,0 +1,7 @@ + +.. xmethod:: datatable.FExpr.isna + :src: src/core/expr/fexpr.cc PyFExpr::isna + :cvar: doc_FExpr_isna + :signature: isna() + + Equivalent to :func:`dt.math.isna(cols)` or `dt.isna(cols)`. diff --git a/docs/api/fexpr/math_isna.rst b/docs/api/fexpr/math_isna.rst deleted file mode 100644 index a2ddd03e60..0000000000 --- a/docs/api/fexpr/math_isna.rst +++ /dev/null @@ -1,7 +0,0 @@ - -.. xmethod:: datatable.FExpr.math_isna - :src: src/core/expr/fexpr.cc PyFExpr::math_isna - :cvar: doc_FExpr_isna - :signature: math_isna() - - Equivalent to :func:`dt.math.isna(cols)`. diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 7da627ec86..f8fc8f0d63 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -46,4 +46,13 @@ 1 | 0 0 0 0 2 | 1 0 0 0 [3 rows x 4 columns] + Note that you can also call `dt.isna` directly: + >>> DT[:, dt.isna(f[:])] + | age born name toy + | bool8 bool8 bool8 bool8 + -- + ----- ----- ----- ----- + 0 | 0 1 0 1 + 1 | 0 0 0 0 + 2 | 1 0 0 0 + [3 rows x 4 columns] diff --git a/src/core/expr/fexpr.cc b/src/core/expr/fexpr.cc index 17a6bb47df..735bc9e4af 100644 --- a/src/core/expr/fexpr.cc +++ b/src/core/expr/fexpr.cc @@ -479,13 +479,13 @@ DECLARE_METHOD(&PyFExpr::first) ->docs(dt::doc_FExpr_first); -oobj PyFExpr::math_isna(const XArgs&) { +oobj PyFExpr::isna(const XArgs&) { auto isnaFn = oobj::import("datatable", "math", "isna"); return isnaFn.call({this}); } -DECLARE_METHOD(&PyFExpr::math_isna) - ->name("math_isna") +DECLARE_METHOD(&PyFExpr::isna) + ->name("isna") ->docs(dt::doc_FExpr_isna); diff --git a/src/core/expr/fexpr.h b/src/core/expr/fexpr.h index c02c0f05f8..decb80acad 100644 --- a/src/core/expr/fexpr.h +++ b/src/core/expr/fexpr.h @@ -192,7 +192,7 @@ class PyFExpr : public py::XObject { py::oobj extend(const py::XArgs&); py::oobj fillna(const py::XArgs&); py::oobj first(const py::XArgs&); - py::oobj math_isna(const py::XArgs&); + py::oobj isna(const py::XArgs&); py::oobj last(const py::XArgs&); py::oobj max(const py::XArgs&); py::oobj mean(const py::XArgs&); diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index 0924b4cc2d..f0cf0a8b50 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -183,26 +183,6 @@ class FExpr_FillNA : public FExpr_Func { return wf; } - - - static Column make_isna_col(Column&& col) { - switch (col.stype()) { - case SType::VOID: return Const_ColumnImpl::make_bool_column(col.nrows(), true); - case SType::BOOL: - case SType::INT8: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::INT16: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::DATE32: - case SType::INT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::TIME64: - case SType::INT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT32: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); - case SType::STR32: - case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); - default: throw RuntimeError(); - } - } - }; diff --git a/src/core/expr/funary/floating.cc b/src/core/expr/funary/floating.cc index 04b332640a..d59f688c1e 100644 --- a/src/core/expr/funary/floating.cc +++ b/src/core/expr/funary/floating.cc @@ -20,7 +20,6 @@ // IN THE SOFTWARE. //------------------------------------------------------------------------------ #include -#include "column/isna.h" #include "documentation.h" #include "expr/funary/pyfn.h" #include "expr/funary/umaker.h" diff --git a/src/datatable/__init__.py b/src/datatable/__init__.py index 88499fe70f..369cbd3d47 100644 --- a/src/datatable/__init__.py +++ b/src/datatable/__init__.py @@ -21,7 +21,7 @@ # IN THE SOFTWARE. #------------------------------------------------------------------------------- from .frame import Frame -from .expr import (min, max, sd, isna, sum, count, countna, first, abs, exp, +from .expr import (min, max, sd, sum, count, countna, first, abs, exp, last, log, log10, f, g, median, cov, corr, nunique) from .lib._datatable import ( as_type, @@ -42,6 +42,7 @@ init_styles, intersect, iread, + isna, join, mean, Namespace, @@ -122,6 +123,7 @@ "int8", "intersect", "iread", + "isna", "join", "last", "log", diff --git a/tests/math/test-isna.py b/tests/math/test-isna.py index 744a78d704..6d62724c70 100644 --- a/tests/math/test-isna.py +++ b/tests/math/test-isna.py @@ -48,7 +48,7 @@ @pytest.mark.parametrize("src", all_sources) def test_isna(src): DT = dt.Frame(src) - RES = DT[:, dt.math.isna(f[0])] + RES = DT[:, dt.isna(f[0])] assert_equals(RES, dt.Frame([(x is None) for x in src])) diff --git a/tests/test-f.py b/tests/test-f.py index 8e17bcf79a..1d0700c575 100644 --- a/tests/test-f.py +++ b/tests/test-f.py @@ -500,7 +500,7 @@ def test_codes(): assert_equals(DT[:, f.A.codes()], DT[:, dt.codes(f.A)]) def test_isna(): - assert str(dt.math.isna(f.A)) == str(f.A.math_isna()) + assert str(dt.math.isna(f.A)) == str(f.A.isna()) DT = dt.Frame(A = [None, 9, 8, 2, 3, None, None, 3, 0, 5, 5, 8, None]) - assert_equals (DT[:, dt.math.isna(f.A)], DT[:, f.A.math_isna()]) + assert_equals (DT[:, dt.math.isna(f.A)], DT[:, f.A.isna()]) From 8fdec204f75b12f790002e4a7949bf95af616b4d Mon Sep 17 00:00:00 2001 From: samukweku Date: Fri, 28 Apr 2023 19:33:11 +1000 Subject: [PATCH 33/53] enhance examples --- docs/api/math/isna.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index f8fc8f0d63..59e5a2cd74 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -46,7 +46,7 @@ 1 | 0 0 0 0 2 | 1 0 0 0 [3 rows x 4 columns] - Note that you can also call `dt.isna` directly: + >>> DT[:, dt.isna(f[:])] | age born name toy | bool8 bool8 bool8 bool8 From 1c7098a3658920de896253c749b5d33c4716c538 Mon Sep 17 00:00:00 2001 From: samukweku Date: Fri, 28 Apr 2023 19:53:48 +1000 Subject: [PATCH 34/53] move fexpr_isna to main folder --- docs/api/math/isna.rst | 4 ++-- src/core/documentation.h | 2 +- src/core/expr/{funary => }/fexpr_isna.cc | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) rename src/core/expr/{funary => }/fexpr_isna.cc (98%) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 59e5a2cd74..802a98136d 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -1,8 +1,8 @@ .. xfunction:: datatable.math.isna - :src: src/core/expr/funary/fexpr_isna.cc pyfn_isna + :src: src/core/expr/fexpr_isna.cc pyfn_isna :tests: tests/math/test-isna.py - :cvar: doc_math_isna + :cvar: doc_isna :signature: isna(cols) Tests if the column elements are missing values. diff --git a/src/core/documentation.h b/src/core/documentation.h index b94ebbdb83..a76cbb5222 100644 --- a/src/core/documentation.h +++ b/src/core/documentation.h @@ -112,7 +112,7 @@ extern const char* doc_math_hypot; extern const char* doc_math_isclose; extern const char* doc_math_isfinite; extern const char* doc_math_isinf; -extern const char* doc_math_isna; +extern const char* doc_isna; extern const char* doc_math_ldexp; extern const char* doc_math_lgamma; extern const char* doc_math_log10; diff --git a/src/core/expr/funary/fexpr_isna.cc b/src/core/expr/fexpr_isna.cc similarity index 98% rename from src/core/expr/funary/fexpr_isna.cc rename to src/core/expr/fexpr_isna.cc index fa67f3f8c1..e96e8f32aa 100644 --- a/src/core/expr/funary/fexpr_isna.cc +++ b/src/core/expr/fexpr_isna.cc @@ -54,7 +54,7 @@ static py::oobj pyfn_isna(const py::XArgs &args) { DECLARE_PYFN(&pyfn_isna) ->name("isna") - ->docs(doc_math_isna) + ->docs(doc_isna) ->arg_names({"cols"}) ->n_positional_args(1) ->n_required_args(1); From ed687fe3a09ced6114b455b2d8d9d9ca6978deae Mon Sep 17 00:00:00 2001 From: samukweku Date: Fri, 28 Apr 2023 20:00:21 +1000 Subject: [PATCH 35/53] add isna to docs --- docs/api/dt/isna.rst | 50 ++++++++++++++++++++++++++++++++++++++++++ docs/api/index-api.rst | 3 +++ docs/api/math/isna.rst | 8 ------- 3 files changed, 53 insertions(+), 8 deletions(-) create mode 100644 docs/api/dt/isna.rst diff --git a/docs/api/dt/isna.rst b/docs/api/dt/isna.rst new file mode 100644 index 0000000000..62d2013efa --- /dev/null +++ b/docs/api/dt/isna.rst @@ -0,0 +1,50 @@ + +.. xfunction:: datatable.isna + :src: src/core/expr/fexpr_isna.cc pyfn_isna + :tests: tests/math/test-isna.py + :cvar: doc_isna + :signature: isna(cols) + + Tests if the column elements are missing values. + + Parameters + ---------- + cols: FExpr + Input columns. + + return: FExpr + f-expression that returns `0` for valid elements and `1` otherwise. + All the resulting columns will have `bool8` stypes + and as many rows/columns as there are in `cols`. + + Examples + -------- + + .. code-block:: python + + >>> from datatable import dt, f + >>> from datetime import datetime + >>> DT = dt.Frame({'age': [5.0, 6.0, None], + ... 'born': [None, + ... datetime(1939, 5, 27, 0, 0), + ... datetime(1940, 4, 25, 0, 0)], + ... 'name': ['Alfred', 'Batman', ''], + ... 'toy': [None, 'Batmobile', 'Joker']}) + >>> DT + | age born name toy + | float64 time64 str32 str32 + -- + ------- ------------------- ------ --------- + 0 | 5 NA Alfred NA + 1 | 6 1939-05-27T00:00:00 Batman Batmobile + 2 | NA 1940-04-25T00:00:00 Joker + [3 rows x 4 columns] + >>> DT[:, dt.isna(f[:])] + | age born name toy + | bool8 bool8 bool8 bool8 + -- + ----- ----- ----- ----- + 0 | 0 1 0 1 + 1 | 0 0 0 0 + 2 | 1 0 0 0 + [3 rows x 4 columns] + + diff --git a/docs/api/index-api.rst b/docs/api/index-api.rst index b9cffbfa03..f2267fcbf8 100644 --- a/docs/api/index-api.rst +++ b/docs/api/index-api.rst @@ -179,6 +179,8 @@ Functions - Calculate covariance between two columns * - :func:`fillna()` - Impute missing values + * - :func:`isna()` + - Test for missing values * - :func:`max()` - Find the largest element per column * - :func:`mean()` @@ -266,6 +268,7 @@ Other init_styles()
intersect()
iread()
+ isna()
join()
last()
max()
diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 802a98136d..86d33ac7ba 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -47,12 +47,4 @@ 2 | 1 0 0 0 [3 rows x 4 columns] - >>> DT[:, dt.isna(f[:])] - | age born name toy - | bool8 bool8 bool8 bool8 - -- + ----- ----- ----- ----- - 0 | 0 1 0 1 - 1 | 0 0 0 0 - 2 | 1 0 0 0 - [3 rows x 4 columns] From c7dcddf7524a587069f92e134fbfce6354d7e4ad Mon Sep 17 00:00:00 2001 From: samukweku Date: Fri, 28 Apr 2023 20:03:56 +1000 Subject: [PATCH 36/53] rename doc_isna to doc_dt_isna --- docs/api/dt/isna.rst | 2 +- docs/api/math/isna.rst | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/api/dt/isna.rst b/docs/api/dt/isna.rst index 62d2013efa..200b84b5c2 100644 --- a/docs/api/dt/isna.rst +++ b/docs/api/dt/isna.rst @@ -2,7 +2,7 @@ .. xfunction:: datatable.isna :src: src/core/expr/fexpr_isna.cc pyfn_isna :tests: tests/math/test-isna.py - :cvar: doc_isna + :cvar: doc_dt_isna :signature: isna(cols) Tests if the column elements are missing values. diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index 86d33ac7ba..ede2982c29 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -2,7 +2,7 @@ .. xfunction:: datatable.math.isna :src: src/core/expr/fexpr_isna.cc pyfn_isna :tests: tests/math/test-isna.py - :cvar: doc_isna + :cvar: doc_dt_isna :signature: isna(cols) Tests if the column elements are missing values. From b32397d65e895653d3f8a7f8fe84b86e82c9bc5d Mon Sep 17 00:00:00 2001 From: samukweku Date: Sat, 29 Apr 2023 07:16:42 +1000 Subject: [PATCH 37/53] doc_dt_isna --- src/core/documentation.h | 2 +- src/core/expr/fexpr_isna.cc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/core/documentation.h b/src/core/documentation.h index a76cbb5222..2d914282cf 100644 --- a/src/core/documentation.h +++ b/src/core/documentation.h @@ -45,6 +45,7 @@ extern const char* doc_dt_ifelse; extern const char* doc_dt_init_styles; extern const char* doc_dt_intersect; extern const char* doc_dt_iread; +extern const char* doc_dt_isna; extern const char* doc_dt_join; extern const char* doc_dt_last; extern const char* doc_dt_max; @@ -112,7 +113,6 @@ extern const char* doc_math_hypot; extern const char* doc_math_isclose; extern const char* doc_math_isfinite; extern const char* doc_math_isinf; -extern const char* doc_isna; extern const char* doc_math_ldexp; extern const char* doc_math_lgamma; extern const char* doc_math_log10; diff --git a/src/core/expr/fexpr_isna.cc b/src/core/expr/fexpr_isna.cc index e96e8f32aa..4d5cb67197 100644 --- a/src/core/expr/fexpr_isna.cc +++ b/src/core/expr/fexpr_isna.cc @@ -54,7 +54,7 @@ static py::oobj pyfn_isna(const py::XArgs &args) { DECLARE_PYFN(&pyfn_isna) ->name("isna") - ->docs(doc_isna) + ->docs(doc_dt_isna) ->arg_names({"cols"}) ->n_positional_args(1) ->n_required_args(1); From a734bcf47b2b0a4b91bb6b6be111b6634514ba6d Mon Sep 17 00:00:00 2001 From: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> Date: Mon, 24 Apr 2023 20:18:24 -0700 Subject: [PATCH 38/53] Implement slicing for categorical columns (#3379) WIP for #1691 --- src/core/column.h | 1 + src/core/column/column_impl.cc | 3 ++- src/core/column/column_impl.h | 11 ++++------- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/src/core/column.h b/src/core/column.h index 1594fdfbba..d8a399decf 100644 --- a/src/core/column.h +++ b/src/core/column.h @@ -119,6 +119,7 @@ class Column size_t nrows() const noexcept; size_t na_count() const; const dt::Type& type() const noexcept; + const dt::Type& data_type() const noexcept; dt::LType ltype() const noexcept; dt::SType stype() const noexcept; diff --git a/src/core/column/column_impl.cc b/src/core/column/column_impl.cc index bf65f17374..78e6336969 100644 --- a/src/core/column/column_impl.cc +++ b/src/core/column/column_impl.cc @@ -240,7 +240,8 @@ const Type& ColumnImpl::data_type() const { } SType ColumnImpl::data_stype() const { - return data_type().stype(); + return type_.is_categorical()? child(0).stype() + : stype(); } diff --git a/src/core/column/column_impl.h b/src/core/column/column_impl.h index a82f73ab8d..f5a50085c6 100644 --- a/src/core/column/column_impl.h +++ b/src/core/column/column_impl.h @@ -95,13 +95,10 @@ class ColumnImpl size_t nrows() const noexcept { return nrows_; } SType stype() const { return type_.stype(); } const Type& type() const { return type_; } - - // For categorical columns these methods will return the stype/type - // of the data the column is backed up with. For all the other column types, - // these methods are equivalent to `stype()`/`type()`. - SType data_stype() const; - const Type& data_type() const; - + const Type& data_type() const { + return type_.is_categorical()? child(0).type() + : type_; + } virtual bool is_virtual() const noexcept = 0; virtual bool computationally_expensive() const { return false; } virtual size_t memory_footprint() const noexcept = 0; From f59c1b66a312ce9b5533af9fd5016db724042534 Mon Sep 17 00:00:00 2001 From: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> Date: Fri, 28 Apr 2023 11:25:04 -0700 Subject: [PATCH 39/53] Minor refactoring of methods to get the underlying column type (#3458) WIP for #1691 --- src/core/column.h | 1 - src/core/column/column_impl.cc | 3 +-- src/core/column/column_impl.h | 11 +++++++---- 3 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/core/column.h b/src/core/column.h index d8a399decf..1594fdfbba 100644 --- a/src/core/column.h +++ b/src/core/column.h @@ -119,7 +119,6 @@ class Column size_t nrows() const noexcept; size_t na_count() const; const dt::Type& type() const noexcept; - const dt::Type& data_type() const noexcept; dt::LType ltype() const noexcept; dt::SType stype() const noexcept; diff --git a/src/core/column/column_impl.cc b/src/core/column/column_impl.cc index 78e6336969..bf65f17374 100644 --- a/src/core/column/column_impl.cc +++ b/src/core/column/column_impl.cc @@ -240,8 +240,7 @@ const Type& ColumnImpl::data_type() const { } SType ColumnImpl::data_stype() const { - return type_.is_categorical()? child(0).stype() - : stype(); + return data_type().stype(); } diff --git a/src/core/column/column_impl.h b/src/core/column/column_impl.h index f5a50085c6..a82f73ab8d 100644 --- a/src/core/column/column_impl.h +++ b/src/core/column/column_impl.h @@ -95,10 +95,13 @@ class ColumnImpl size_t nrows() const noexcept { return nrows_; } SType stype() const { return type_.stype(); } const Type& type() const { return type_; } - const Type& data_type() const { - return type_.is_categorical()? child(0).type() - : type_; - } + + // For categorical columns these methods will return the stype/type + // of the data the column is backed up with. For all the other column types, + // these methods are equivalent to `stype()`/`type()`. + SType data_stype() const; + const Type& data_type() const; + virtual bool is_virtual() const noexcept = 0; virtual bool computationally_expensive() const { return false; } virtual size_t memory_footprint() const noexcept = 0; From 3df983fa8b4ba2aeaad1c720d553e607187b3bde Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Wed, 3 May 2023 09:36:42 +1000 Subject: [PATCH 40/53] Update docs/api/dt/isna.rst Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- docs/api/dt/isna.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/dt/isna.rst b/docs/api/dt/isna.rst index 200b84b5c2..a3b53a84a3 100644 --- a/docs/api/dt/isna.rst +++ b/docs/api/dt/isna.rst @@ -5,7 +5,7 @@ :cvar: doc_dt_isna :signature: isna(cols) - Tests if the column elements are missing values. + Test if the column elements are missing values. Parameters ---------- From d41570fb49accc1159c86b442f8323ad928df227 Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Wed, 3 May 2023 09:37:09 +1000 Subject: [PATCH 41/53] Update docs/api/fexpr.rst Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- docs/api/fexpr.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/api/fexpr.rst b/docs/api/fexpr.rst index bee6eb478c..e81053b6fa 100644 --- a/docs/api/fexpr.rst +++ b/docs/api/fexpr.rst @@ -191,7 +191,7 @@ - Same as :func:`dt.first()`. * - :meth:`.isna()` - - Same as :func:`dt.math.isna()`. + - Same as :func:`dt.isna()`. * - :meth:`.last()` - Same as :func:`dt.last()`. From 55efdfeeafb1b98ddbaa1d0516a55470188218e4 Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Wed, 3 May 2023 09:40:36 +1000 Subject: [PATCH 42/53] Update docs/api/math/isna.rst Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- docs/api/math/isna.rst | 42 +----------------------------------------- 1 file changed, 1 insertion(+), 41 deletions(-) diff --git a/docs/api/math/isna.rst b/docs/api/math/isna.rst index ede2982c29..86aa7e0f24 100644 --- a/docs/api/math/isna.rst +++ b/docs/api/math/isna.rst @@ -5,46 +5,6 @@ :cvar: doc_dt_isna :signature: isna(cols) - Tests if the column elements are missing values. - - Parameters - ---------- - cols: FExpr - Input columns. - - return: FExpr - f-expression that returns `0` for valid elements and `1` otherwise. - All the resulting columns will have `bool8` stypes - and as many rows/columns as there are in `cols`. - - Examples - -------- - - .. code-block:: python - - >>> from datatable import dt, f - >>> from datetime import datetime - >>> DT = dt.Frame({'age': [5.0, 6.0, None], - ... 'born': [None, - ... datetime(1939, 5, 27, 0, 0), - ... datetime(1940, 4, 25, 0, 0)], - ... 'name': ['Alfred', 'Batman', ''], - ... 'toy': [None, 'Batmobile', 'Joker']}) - >>> DT - | age born name toy - | float64 time64 str32 str32 - -- + ------- ------------------- ------ --------- - 0 | 5 NA Alfred NA - 1 | 6 1939-05-27T00:00:00 Batman Batmobile - 2 | NA 1940-04-25T00:00:00 Joker - [3 rows x 4 columns] - >>> DT[:, dt.math.isna(f[:])] - | age born name toy - | bool8 bool8 bool8 bool8 - -- + ----- ----- ----- ----- - 0 | 0 1 0 1 - 1 | 0 0 0 0 - 2 | 1 0 0 0 - [3 rows x 4 columns] + Same as :func:`dt.isna()`. From 46535b3c906b3b467f379f5343ecd864b84981d6 Mon Sep 17 00:00:00 2001 From: samukweku Date: Mon, 13 Mar 2023 23:43:12 +1100 Subject: [PATCH 43/53] implemenation of isna fexpr --- src/core/expr/fexpr_isna.cc | 2 +- src/core/expr/fexpr_isna.h | 85 +++++++++++++++++++++++++++++++++++++ src/datatable/__init__.py | 5 +-- src/datatable/expr/math.py | 2 +- src/datatable/math.py | 1 - tests/math/test-isna.py | 2 +- 6 files changed, 90 insertions(+), 7 deletions(-) create mode 100644 src/core/expr/fexpr_isna.h diff --git a/src/core/expr/fexpr_isna.cc b/src/core/expr/fexpr_isna.cc index 4d5cb67197..30c83f874c 100644 --- a/src/core/expr/fexpr_isna.cc +++ b/src/core/expr/fexpr_isna.cc @@ -60,4 +60,4 @@ DECLARE_PYFN(&pyfn_isna) ->n_required_args(1); -}} // dt::expr +}} // dt::expr \ No newline at end of file diff --git a/src/core/expr/fexpr_isna.h b/src/core/expr/fexpr_isna.h new file mode 100644 index 0000000000..276227e77a --- /dev/null +++ b/src/core/expr/fexpr_isna.h @@ -0,0 +1,85 @@ +//------------------------------------------------------------------------------ +// Copyright 2022-2023 H2O.ai +// +// Permission is hereby granted, free of charge, to any person obtaining a +// copy of this software and associated documentation files (the "Software"), +// to deal in the Software without restriction, including without limitation +// the rights to use, copy, modify, merge, publish, distribute, sublicense, +// and/or sell copies of the Software, and to permit persons to whom the +// Software is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +// IN THE SOFTWARE. +//------------------------------------------------------------------------------ +<<<<<<<< HEAD:src/core/expr/fexpr_isna.cc +#include "column/const.h" +#include "column/isna.h" +#include "expr/fexpr_column.h" +#include "documentation.h" +#include "expr/fexpr_func_unary.h" +#include "expr/eval_context.h" +#include "expr/workframe.h" +#include "python/xargs.h" +#include "stype.h" +======== +#ifndef dt_EXPR_FEXPR_ISNA_h +#define dt_EXPR_FEXPR_ISNA_h +#include "expr/fexpr_func.h" +>>>>>>>> da5f26d3 (implemenation of isna fexpr):src/core/expr/fexpr_isna.h +namespace dt { +namespace expr { + + +<<<<<<<< HEAD:src/core/expr/fexpr_isna.cc +class FExpr_ISNA : public FExpr_FuncUnary { + public: + using FExpr_FuncUnary::FExpr_FuncUnary; + + + std::string name() const override { + return "isna"; + } + + Column evaluate1(Column&& col) const override{ + return make_isna_col(std::move(col)); + } +}; + + +static py::oobj pyfn_isna(const py::XArgs &args) { + auto isna = args[0].to_oobj(); + return PyFExpr::make(new FExpr_ISNA(as_fexpr(isna))); +} + +DECLARE_PYFN(&pyfn_isna) + ->name("isna") + ->docs(doc_dt_isna) + ->arg_names({"cols"}) + ->n_positional_args(1) + ->n_required_args(1); + + +}} // dt::expr +======== +class FExpr_ISNA : public FExpr_Func { + private: + ptrExpr arg_; + + public: + FExpr_ISNA(ptrExpr&& arg); + std::string repr() const override; + Workframe evaluate_n(EvalContext& ctx) const override; +}; + + +}} // dt::expr +#endif +>>>>>>>> da5f26d3 (implemenation of isna fexpr):src/core/expr/fexpr_isna.h diff --git a/src/datatable/__init__.py b/src/datatable/__init__.py index 369cbd3d47..c95aceadf6 100644 --- a/src/datatable/__init__.py +++ b/src/datatable/__init__.py @@ -21,8 +21,8 @@ # IN THE SOFTWARE. #------------------------------------------------------------------------------- from .frame import Frame -from .expr import (min, max, sd, sum, count, countna, first, abs, exp, - last, log, log10, f, g, median, cov, corr, nunique) +from .expr import (min, max, sd, sum, count, first, abs, exp, + last, log, log10, f, g, median, cov, corr, countna, nunique) from .lib._datatable import ( as_type, by, @@ -123,7 +123,6 @@ "int8", "intersect", "iread", - "isna", "join", "last", "log", diff --git a/src/datatable/expr/math.py b/src/datatable/expr/math.py index d5c57245b3..5dc51289e5 100644 --- a/src/datatable/expr/math.py +++ b/src/datatable/expr/math.py @@ -9,7 +9,7 @@ # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, +# distributed undesrc = [False, True, False, False, True]r the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. diff --git a/src/datatable/math.py b/src/datatable/math.py index c4660bdad6..7c243a2a27 100644 --- a/src/datatable/math.py +++ b/src/datatable/math.py @@ -48,7 +48,6 @@ isclose, isfinite, isinf, - isna, ldexp, lgamma, log, diff --git a/tests/math/test-isna.py b/tests/math/test-isna.py index 6d62724c70..744a78d704 100644 --- a/tests/math/test-isna.py +++ b/tests/math/test-isna.py @@ -48,7 +48,7 @@ @pytest.mark.parametrize("src", all_sources) def test_isna(src): DT = dt.Frame(src) - RES = DT[:, dt.isna(f[0])] + RES = DT[:, dt.math.isna(f[0])] assert_equals(RES, dt.Frame([(x is None) for x in src])) From 88567262fa280d75686d6710ea812fa825fe0e83 Mon Sep 17 00:00:00 2001 From: samukweku Date: Fri, 28 Apr 2023 19:28:34 +1000 Subject: [PATCH 44/53] update based on feedback --- src/datatable/__init__.py | 5 +++-- tests/math/test-isna.py | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/datatable/__init__.py b/src/datatable/__init__.py index c95aceadf6..369cbd3d47 100644 --- a/src/datatable/__init__.py +++ b/src/datatable/__init__.py @@ -21,8 +21,8 @@ # IN THE SOFTWARE. #------------------------------------------------------------------------------- from .frame import Frame -from .expr import (min, max, sd, sum, count, first, abs, exp, - last, log, log10, f, g, median, cov, corr, countna, nunique) +from .expr import (min, max, sd, sum, count, countna, first, abs, exp, + last, log, log10, f, g, median, cov, corr, nunique) from .lib._datatable import ( as_type, by, @@ -123,6 +123,7 @@ "int8", "intersect", "iread", + "isna", "join", "last", "log", diff --git a/tests/math/test-isna.py b/tests/math/test-isna.py index 744a78d704..6d62724c70 100644 --- a/tests/math/test-isna.py +++ b/tests/math/test-isna.py @@ -48,7 +48,7 @@ @pytest.mark.parametrize("src", all_sources) def test_isna(src): DT = dt.Frame(src) - RES = DT[:, dt.math.isna(f[0])] + RES = DT[:, dt.isna(f[0])] assert_equals(RES, dt.Frame([(x is None) for x in src])) From 3a6d83bb87c312aa92e1bb25da342e0e429e0394 Mon Sep 17 00:00:00 2001 From: samukweku Date: Wed, 3 May 2023 20:34:11 +1000 Subject: [PATCH 45/53] fixes based on feedback --- docs/api/fexpr/isna.rst | 2 +- src/core/expr/fexpr_isna.cc | 3 +- src/core/expr/fexpr_isna.h | 85 ----------------------------------- src/datatable/expr/math.py | 2 +- src/datatable/math.py | 5 +-- tests/ijby/test-assign.py | 2 +- tests/math/test-isna.py | 2 +- tests/munging/test-delete.py | 5 +-- tests/munging/test-dt-rows.py | 3 +- tests/test-f.py | 2 +- tests/test-import-all.py | 2 +- 11 files changed, 12 insertions(+), 101 deletions(-) delete mode 100644 src/core/expr/fexpr_isna.h diff --git a/docs/api/fexpr/isna.rst b/docs/api/fexpr/isna.rst index b80ae238f4..6611330e23 100644 --- a/docs/api/fexpr/isna.rst +++ b/docs/api/fexpr/isna.rst @@ -4,4 +4,4 @@ :cvar: doc_FExpr_isna :signature: isna() - Equivalent to :func:`dt.math.isna(cols)` or `dt.isna(cols)`. + Equivalent to :func:`dt.isna(cols)`. diff --git a/src/core/expr/fexpr_isna.cc b/src/core/expr/fexpr_isna.cc index 30c83f874c..4e90928edd 100644 --- a/src/core/expr/fexpr_isna.cc +++ b/src/core/expr/fexpr_isna.cc @@ -60,4 +60,5 @@ DECLARE_PYFN(&pyfn_isna) ->n_required_args(1); -}} // dt::expr \ No newline at end of file +}} // dt::expr + diff --git a/src/core/expr/fexpr_isna.h b/src/core/expr/fexpr_isna.h deleted file mode 100644 index 276227e77a..0000000000 --- a/src/core/expr/fexpr_isna.h +++ /dev/null @@ -1,85 +0,0 @@ -//------------------------------------------------------------------------------ -// Copyright 2022-2023 H2O.ai -// -// Permission is hereby granted, free of charge, to any person obtaining a -// copy of this software and associated documentation files (the "Software"), -// to deal in the Software without restriction, including without limitation -// the rights to use, copy, modify, merge, publish, distribute, sublicense, -// and/or sell copies of the Software, and to permit persons to whom the -// Software is furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in -// all copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS -// IN THE SOFTWARE. -//------------------------------------------------------------------------------ -<<<<<<<< HEAD:src/core/expr/fexpr_isna.cc -#include "column/const.h" -#include "column/isna.h" -#include "expr/fexpr_column.h" -#include "documentation.h" -#include "expr/fexpr_func_unary.h" -#include "expr/eval_context.h" -#include "expr/workframe.h" -#include "python/xargs.h" -#include "stype.h" -======== -#ifndef dt_EXPR_FEXPR_ISNA_h -#define dt_EXPR_FEXPR_ISNA_h -#include "expr/fexpr_func.h" ->>>>>>>> da5f26d3 (implemenation of isna fexpr):src/core/expr/fexpr_isna.h -namespace dt { -namespace expr { - - -<<<<<<<< HEAD:src/core/expr/fexpr_isna.cc -class FExpr_ISNA : public FExpr_FuncUnary { - public: - using FExpr_FuncUnary::FExpr_FuncUnary; - - - std::string name() const override { - return "isna"; - } - - Column evaluate1(Column&& col) const override{ - return make_isna_col(std::move(col)); - } -}; - - -static py::oobj pyfn_isna(const py::XArgs &args) { - auto isna = args[0].to_oobj(); - return PyFExpr::make(new FExpr_ISNA(as_fexpr(isna))); -} - -DECLARE_PYFN(&pyfn_isna) - ->name("isna") - ->docs(doc_dt_isna) - ->arg_names({"cols"}) - ->n_positional_args(1) - ->n_required_args(1); - - -}} // dt::expr -======== -class FExpr_ISNA : public FExpr_Func { - private: - ptrExpr arg_; - - public: - FExpr_ISNA(ptrExpr&& arg); - std::string repr() const override; - Workframe evaluate_n(EvalContext& ctx) const override; -}; - - -}} // dt::expr -#endif ->>>>>>>> da5f26d3 (implemenation of isna fexpr):src/core/expr/fexpr_isna.h diff --git a/src/datatable/expr/math.py b/src/datatable/expr/math.py index 5dc51289e5..d5c57245b3 100644 --- a/src/datatable/expr/math.py +++ b/src/datatable/expr/math.py @@ -9,7 +9,7 @@ # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software -# distributed undesrc = [False, True, False, False, True]r the License is distributed on an "AS IS" BASIS, +# distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. diff --git a/src/datatable/math.py b/src/datatable/math.py index 7c243a2a27..eafe3822b9 100644 --- a/src/datatable/math.py +++ b/src/datatable/math.py @@ -48,6 +48,7 @@ isclose, isfinite, isinf, + isna, ldexp, lgamma, log, @@ -74,10 +75,6 @@ from datatable.lib import core import math -__all__ = [ - "isna" -] - e = 2.718281828459045 golden = 1.618033988749895 pi = 3.141592653589793 diff --git a/tests/ijby/test-assign.py b/tests/ijby/test-assign.py index f6940707a9..5f38c33253 100644 --- a/tests/ijby/test-assign.py +++ b/tests/ijby/test-assign.py @@ -231,7 +231,7 @@ def test_assign_to_sliced_frame(): def test_assign_string_columns(): DT = dt.Frame(A=["One", "two", "three", None, "five"]) - DT[dt.math.isna(f.A), f.A] = dt.Frame(["FOUR"]) + DT[dt.isna(f.A), f.A] = dt.Frame(["FOUR"]) assert_equals(DT, dt.Frame(A=["One", "two", "three", "FOUR", "five"])) diff --git a/tests/math/test-isna.py b/tests/math/test-isna.py index 6d62724c70..744a78d704 100644 --- a/tests/math/test-isna.py +++ b/tests/math/test-isna.py @@ -48,7 +48,7 @@ @pytest.mark.parametrize("src", all_sources) def test_isna(src): DT = dt.Frame(src) - RES = DT[:, dt.isna(f[0])] + RES = DT[:, dt.math.isna(f[0])] assert_equals(RES, dt.Frame([(x is None) for x in src])) diff --git a/tests/munging/test-delete.py b/tests/munging/test-delete.py index bb184597a2..3cbb636c04 100644 --- a/tests/munging/test-delete.py +++ b/tests/munging/test-delete.py @@ -24,7 +24,6 @@ import datatable as dt import pytest from datatable import f, g, ltype -from datatable.math import isna from datatable.internal import frame_integrity_check from tests import assert_equals @@ -350,7 +349,7 @@ def test_del_rows_filter(): def test_del_rows_nas(): d0 = dt.Frame({"A": [1, 5, None, 12, 7, None, -3]}) - del d0[isna(f.A), :] + del d0[dt.isna(f.A), :] frame_integrity_check(d0) assert d0.to_list() == [[1, 5, 12, 7, -3]] @@ -367,7 +366,7 @@ def test_del_rows_from_view1(): def test_del_rows_from_view2(): f0 = dt.Frame([1, 3, None, 4, 5, None, None, 2, None, None, None]) f1 = f0[5:, :] - del f1[isna(f[0]), :] + del f1[dt.isna(f[0]), :] assert f1.to_list() == [[2]] diff --git a/tests/munging/test-dt-rows.py b/tests/munging/test-dt-rows.py index 041c3db2f5..ac9b2c4348 100644 --- a/tests/munging/test-dt-rows.py +++ b/tests/munging/test-dt-rows.py @@ -718,8 +718,7 @@ def test_rows_unary_minus(df1): def test_rows_isna(df1): - from datatable.math import isna - dt1 = df1[isna(f.A), :] + dt1 = df1[dt.isna(f.A), :] frame_integrity_check(dt1) assert dt1.names == df1.names assert dt1.to_list() == [[None, None], [None, 8]] diff --git a/tests/test-f.py b/tests/test-f.py index 1d0700c575..d987c5a508 100644 --- a/tests/test-f.py +++ b/tests/test-f.py @@ -502,5 +502,5 @@ def test_codes(): def test_isna(): assert str(dt.math.isna(f.A)) == str(f.A.isna()) DT = dt.Frame(A = [None, 9, 8, 2, 3, None, None, 3, 0, 5, 5, 8, None]) - assert_equals (DT[:, dt.math.isna(f.A)], DT[:, f.A.isna()]) + assert_equals (DT[:, dt.isna(f.A)], DT[:, f.A.isna()]) diff --git a/tests/test-import-all.py b/tests/test-import-all.py index 7a03ca7b95..e227a5fc34 100644 --- a/tests/test-import-all.py +++ b/tests/test-import-all.py @@ -78,7 +78,7 @@ def test_stypes(): def test_ufuncs(): assert dt.abs != abs assert exp - assert dt.math.isna + assert dt.isna assert log assert log10 From b06f1f5168b0a603cc23c780f115ac87fb766ad7 Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Fri, 5 May 2023 17:49:38 +1000 Subject: [PATCH 46/53] Update src/core/column/isna.h Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- src/core/column/isna.h | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 52b87527c2..572309c794 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -77,7 +77,9 @@ static Column make_isna_col(Column&& col) { case SType::FLOAT64: return Column(new Isna_ColumnImpl(std::move(col))); case SType::STR32: case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); - default: throw RuntimeError(); + default: + throw RuntimeError() << "Function `isna` cannot be applied to a " + "column of type `" << col.stype()) << "`"; } } From 95590b6cd6e69e8fc751f4d048404eb42573766f Mon Sep 17 00:00:00 2001 From: Samuel Oranyeli Date: Fri, 5 May 2023 17:49:51 +1000 Subject: [PATCH 47/53] Update src/core/expr/fexpr_isna.cc Co-authored-by: Oleksiy <35204136+oleksiyskononenko@users.noreply.github.com> --- src/core/expr/fexpr_isna.cc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/expr/fexpr_isna.cc b/src/core/expr/fexpr_isna.cc index 4e90928edd..424a2d698c 100644 --- a/src/core/expr/fexpr_isna.cc +++ b/src/core/expr/fexpr_isna.cc @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright 2022-2023 H2O.ai +// Copyright 2023 H2O.ai // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), From 7e70e2525a023ae2a43955e3e00bb9d601024e77 Mon Sep 17 00:00:00 2001 From: samukweku Date: Fri, 5 May 2023 17:50:56 +1000 Subject: [PATCH 48/53] remove irrelevant import --- src/datatable/math.py | 1 - 1 file changed, 1 deletion(-) diff --git a/src/datatable/math.py b/src/datatable/math.py index eafe3822b9..3e52b75b34 100644 --- a/src/datatable/math.py +++ b/src/datatable/math.py @@ -73,7 +73,6 @@ ) from datatable.lib import core -import math e = 2.718281828459045 golden = 1.618033988749895 From aa2ee23aa45f0e2c097439502e6392446cb23792 Mon Sep 17 00:00:00 2001 From: samukweku Date: Fri, 5 May 2023 18:05:38 +1000 Subject: [PATCH 49/53] updates based on code review --- src/core/column/isna.h | 2 +- src/core/expr/fbinary/fexpr__eq__.cc | 2 +- src/core/expr/fnary/rowcount.cc | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 572309c794..325a0e6e12 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -79,7 +79,7 @@ static Column make_isna_col(Column&& col) { case SType::STR64: return Column(new Isna_ColumnImpl(std::move(col))); default: throw RuntimeError() << "Function `isna` cannot be applied to a " - "column of type `" << col.stype()) << "`"; + "column of type `" << col.stype() << "`"; } } diff --git a/src/core/expr/fbinary/fexpr__eq__.cc b/src/core/expr/fbinary/fexpr__eq__.cc index 08c65b37e4..4f3eb9c0a3 100644 --- a/src/core/expr/fbinary/fexpr__eq__.cc +++ b/src/core/expr/fbinary/fexpr__eq__.cc @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright 2019-2021 H2O.ai +// Copyright 2019-2023 H2O.ai // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), diff --git a/src/core/expr/fnary/rowcount.cc b/src/core/expr/fnary/rowcount.cc index 7b0422e757..40de6f03b8 100644 --- a/src/core/expr/fnary/rowcount.cc +++ b/src/core/expr/fnary/rowcount.cc @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright 2019-2021 H2O.ai +// Copyright 2019-2023 H2O.ai // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), From 05f51add2d78337e107966b64093ee1ff093271e Mon Sep 17 00:00:00 2001 From: samukweku Date: Sat, 6 May 2023 22:28:34 +1000 Subject: [PATCH 50/53] fix for isna with non fexprs --- src/datatable/__init__.py | 4 +--- src/datatable/expr/__init__.py | 1 + src/datatable/expr/math.py | 15 ++++++++++++--- src/datatable/math.py | 17 ++++++++++++----- tests/math/test-isna.py | 28 ++++++++++++++-------------- 5 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/datatable/__init__.py b/src/datatable/__init__.py index 369cbd3d47..9981d4c8a7 100644 --- a/src/datatable/__init__.py +++ b/src/datatable/__init__.py @@ -21,7 +21,7 @@ # IN THE SOFTWARE. #------------------------------------------------------------------------------- from .frame import Frame -from .expr import (min, max, sd, sum, count, countna, first, abs, exp, +from .expr import (min, max, sd, sum, count, countna, first, abs, exp, isna, last, log, log10, f, g, median, cov, corr, nunique) from .lib._datatable import ( as_type, @@ -42,7 +42,6 @@ init_styles, intersect, iread, - isna, join, mean, Namespace, @@ -123,7 +122,6 @@ "int8", "intersect", "iread", - "isna", "join", "last", "log", diff --git a/src/datatable/expr/__init__.py b/src/datatable/expr/__init__.py index da91b8a9c4..17380a1f6a 100644 --- a/src/datatable/expr/__init__.py +++ b/src/datatable/expr/__init__.py @@ -47,3 +47,4 @@ "sum", "nunique", ) + diff --git a/src/datatable/expr/math.py b/src/datatable/expr/math.py index d5c57245b3..9f95db3c4d 100644 --- a/src/datatable/expr/math.py +++ b/src/datatable/expr/math.py @@ -1,5 +1,5 @@ #!/usr/bin/env python3 -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- # Copyright 2018 H2O.ai # # Licensed under the Apache License, Version 2.0 (the "License"); @@ -13,14 +13,23 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- from datatable.lib import core +import math __all__ = ("abs", "exp", "log", "log10", "isna") + +def isna(iterable): + if isinstance(iterable, core.FExpr): + return core.isna(iterable) + return (iterable is None) or (iterable is math.nan) + + # Deprecated, use math namespace instead -isna = core.isna abs = core.abs exp = core.exp log = core.log log10 = core.log10 + + diff --git a/src/datatable/math.py b/src/datatable/math.py index 3e52b75b34..a534c16602 100644 --- a/src/datatable/math.py +++ b/src/datatable/math.py @@ -1,5 +1,5 @@ #!/usr/bin/env python -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- # Copyright 2018 H2O.ai # # Permission is hereby granted, free of charge, to any person obtaining a @@ -19,7 +19,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- from .lib._datatable import ( abs, arccos, @@ -73,11 +73,18 @@ ) from datatable.lib import core +import math + + +def isna(iterable): + if isinstance(iterable, core.FExpr): + return core.isna(iterable) + return (iterable is None) or (iterable is math.nan) + e = 2.718281828459045 golden = 1.618033988749895 pi = 3.141592653589793 tau = 6.283185307179586 -nan = float('nan') -inf = float('inf') - +nan = float("nan") +inf = float("inf") diff --git a/tests/math/test-isna.py b/tests/math/test-isna.py index 744a78d704..0f6681e61d 100644 --- a/tests/math/test-isna.py +++ b/tests/math/test-isna.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- # Copyright 2018-2021 H2O.ai # # Permission is hereby granted, free of charge, to any person obtaining a @@ -20,7 +20,7 @@ # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS # IN THE SOFTWARE. -#------------------------------------------------------------------------------- +# ------------------------------------------------------------------------------- import math import pytest from datetime import date @@ -35,16 +35,14 @@ [None, -1, 0, 26, -3], [2**31 - 2, -(2**31 - 1), 0, -1, 1], [9.5, 0.2, 5.4857301, -3.14159265338979], - [1.1, 2.3e12, -.5, None, math.inf, 0.0], + [1.1, 2.3e12, -0.5, None, math.inf, 0.0], ["foo", "bbar", "baz"], [None, "", " ", " ", None, "\x00"], list("qwertyuiiop[]asdfghjkl;'zxcvbnm,./`1234567890-="), - [date(2001, 1, 4), date(2005, 7, 15), None, None, None] + [date(2001, 1, 4), date(2005, 7, 15), None, None, None], ] - - @pytest.mark.parametrize("src", all_sources) def test_isna(src): DT = dt.Frame(src) @@ -54,6 +52,7 @@ def test_isna(src): def test_isna2(): from math import nan + DT = dt.Frame(A=[1, None, 2, 5, None, 3.6, nan, -4.899]) DT1 = DT[~dt.math.isna(f.A), :] assert DT1.types == DT.types @@ -64,20 +63,21 @@ def test_isna2(): def test_isna_joined(): # See issue #2109 DT = dt.Frame(A=[None, 4, 3, 2, 1]) - JDT = dt.Frame(A=[0, 1, 3, 7], - B=['a', 'b', 'c', 'd'], - C=[0.25, 0.5, 0.75, 1.0], - D=[22, 33, 44, 55], - E=[True, False, True, False]) - JDT.key = 'A' + JDT = dt.Frame( + A=[0, 1, 3, 7], + B=["a", "b", "c", "d"], + C=[0.25, 0.5, 0.75, 1.0], + D=[22, 33, 44, 55], + E=[True, False, True, False], + ) + JDT.key = "A" RES = DT[:, dt.math.isna(g[1:]), join(JDT)] dt.internal.frame_integrity_check(RES) assert RES.to_list() == [[True, True, False, True, False]] * 4 -@pytest.mark.xfail(reason="scalar NA check not supported") + @pytest.mark.parametrize("src", all_sources[:-1]) def test_isna_scalar(src): for val in src: assert dt.math.isna(val) == (val is None or val is math.nan) - From aae69c889326b89ab6514bbe14cd9be023bba6ec Mon Sep 17 00:00:00 2001 From: samukweku Date: Sun, 7 May 2023 08:15:31 +1000 Subject: [PATCH 51/53] import isna from a single point --- src/datatable/__init__.py | 3 ++- src/datatable/expr/__init__.py | 3 +-- src/datatable/expr/math.py | 10 +--------- src/datatable/math.py | 1 - 4 files changed, 4 insertions(+), 13 deletions(-) diff --git a/src/datatable/__init__.py b/src/datatable/__init__.py index 9981d4c8a7..a3b01caeb5 100644 --- a/src/datatable/__init__.py +++ b/src/datatable/__init__.py @@ -21,7 +21,8 @@ # IN THE SOFTWARE. #------------------------------------------------------------------------------- from .frame import Frame -from .expr import (min, max, sd, sum, count, countna, first, abs, exp, isna, +from .math import isna +from .expr import (min, max, sd, sum, count, countna, first, abs, exp, last, log, log10, f, g, median, cov, corr, nunique) from .lib._datatable import ( as_type, diff --git a/src/datatable/expr/__init__.py b/src/datatable/expr/__init__.py index 17380a1f6a..3f44bcadf0 100644 --- a/src/datatable/expr/__init__.py +++ b/src/datatable/expr/__init__.py @@ -21,7 +21,7 @@ # IN THE SOFTWARE. #------------------------------------------------------------------------------- from .expr import f, g, Expr -from .math import abs, log, log10, exp, isna +from .math import abs, log, log10, exp from .reduce import ( sum, count, countna, first, last, median, min, max, sd, cov, corr, nunique) @@ -36,7 +36,6 @@ "f", "first", "g", - "isna", "last", "log", "log10", diff --git a/src/datatable/expr/math.py b/src/datatable/expr/math.py index 9f95db3c4d..de7638ef5b 100644 --- a/src/datatable/expr/math.py +++ b/src/datatable/expr/math.py @@ -15,16 +15,8 @@ # limitations under the License. # ------------------------------------------------------------------------------- from datatable.lib import core -import math - -__all__ = ("abs", "exp", "log", "log10", "isna") - - -def isna(iterable): - if isinstance(iterable, core.FExpr): - return core.isna(iterable) - return (iterable is None) or (iterable is math.nan) +__all__ = ("abs", "exp", "log", "log10") # Deprecated, use math namespace instead abs = core.abs diff --git a/src/datatable/math.py b/src/datatable/math.py index a534c16602..ed2f19e8dd 100644 --- a/src/datatable/math.py +++ b/src/datatable/math.py @@ -48,7 +48,6 @@ isclose, isfinite, isinf, - isna, ldexp, lgamma, log, From aaec02e8bab408724211e82c8a9b36ee7b5fe6a1 Mon Sep 17 00:00:00 2001 From: samukweku Date: Sun, 7 May 2023 08:23:35 +1000 Subject: [PATCH 52/53] copyright date updates --- src/core/column/isna.h | 2 +- src/core/expr/fexpr_fillna.cc | 2 +- src/datatable/__init__.py | 2 +- src/datatable/expr/__init__.py | 2 +- src/datatable/expr/math.py | 2 +- src/datatable/math.py | 2 +- tests/test-f.py | 2 +- 7 files changed, 7 insertions(+), 7 deletions(-) diff --git a/src/core/column/isna.h b/src/core/column/isna.h index 325a0e6e12..08d7764024 100644 --- a/src/core/column/isna.h +++ b/src/core/column/isna.h @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright 2019-2021 H2O.ai +// Copyright 2019-2023 H2O.ai // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), diff --git a/src/core/expr/fexpr_fillna.cc b/src/core/expr/fexpr_fillna.cc index f0cf0a8b50..5449dd6680 100644 --- a/src/core/expr/fexpr_fillna.cc +++ b/src/core/expr/fexpr_fillna.cc @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright 2022 H2O.ai +// Copyright 2022-2023 H2O.ai // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), diff --git a/src/datatable/__init__.py b/src/datatable/__init__.py index a3b01caeb5..6592f657ab 100644 --- a/src/datatable/__init__.py +++ b/src/datatable/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python #------------------------------------------------------------------------------- -# Copyright 2018-2022 H2O.ai +# Copyright 2018-2023 H2O.ai # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), diff --git a/src/datatable/expr/__init__.py b/src/datatable/expr/__init__.py index 3f44bcadf0..7f7c9f8cf5 100644 --- a/src/datatable/expr/__init__.py +++ b/src/datatable/expr/__init__.py @@ -1,6 +1,6 @@ #!/usr/bin/env python #------------------------------------------------------------------------------- -# Copyright 2018-2022 H2O.ai +# Copyright 2018-2023 H2O.ai # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), diff --git a/src/datatable/expr/math.py b/src/datatable/expr/math.py index de7638ef5b..f499528a1b 100644 --- a/src/datatable/expr/math.py +++ b/src/datatable/expr/math.py @@ -1,6 +1,6 @@ #!/usr/bin/env python3 # ------------------------------------------------------------------------------- -# Copyright 2018 H2O.ai +# Copyright 2018-2023 H2O.ai # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/datatable/math.py b/src/datatable/math.py index ed2f19e8dd..63c89b11cb 100644 --- a/src/datatable/math.py +++ b/src/datatable/math.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # ------------------------------------------------------------------------------- -# Copyright 2018 H2O.ai +# Copyright 2018-2023 H2O.ai # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), diff --git a/tests/test-f.py b/tests/test-f.py index d987c5a508..639339fdbf 100644 --- a/tests/test-f.py +++ b/tests/test-f.py @@ -1,7 +1,7 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- #------------------------------------------------------------------------------- -# Copyright 2019-2022 H2O.ai +# Copyright 2019-2023 H2O.ai # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), From 46f53fe5a28fcbd68e2caf18cd91b3d0b52156e4 Mon Sep 17 00:00:00 2001 From: samukweku Date: Sun, 7 May 2023 08:32:12 +1000 Subject: [PATCH 53/53] update copyright dates --- src/core/expr/fexpr.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/core/expr/fexpr.h b/src/core/expr/fexpr.h index decb80acad..8cf92bd5e7 100644 --- a/src/core/expr/fexpr.h +++ b/src/core/expr/fexpr.h @@ -1,5 +1,5 @@ //------------------------------------------------------------------------------ -// Copyright 2020 H2O.ai +// Copyright 2020-2023 H2O.ai // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"),