Skip to content
11 changes: 11 additions & 0 deletions bigframes/core/compile/ibis_compiler/scalar_op_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
from bigframes.core import agg_expressions, ordering
import bigframes.core.compile.ibis_types
import bigframes.core.expression as ex
from bigframes.operations import numeric_ops

if TYPE_CHECKING:
import bigframes.operations as ops
Expand Down Expand Up @@ -267,3 +268,13 @@ def _convert_range_ordering_to_table_value(

# Singleton compiler
scalar_op_compiler = ExpressionCompiler()


@scalar_op_compiler.register_unary_op(numeric_ops.isnanornull_op)
def isnanornull(arg):
return arg.isnan() | arg.isnull()


@scalar_op_compiler.register_unary_op(numeric_ops.isfinite_op)
def isfinite(arg):
return arg.isinf().not_() & arg.isnan().not_()
8 changes: 8 additions & 0 deletions bigframes/core/compile/polars/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,14 @@ def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
return input.ceil()

@compile_op.register(num_ops.IsNanOrNullOp)
def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
return input.is_nan() | input.is_null()

@compile_op.register(num_ops.IsFiniteOp)
def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
return input.is_finite()

@compile_op.register(num_ops.PosOp)
def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
return input.__pos__()
Expand Down
13 changes: 13 additions & 0 deletions bigframes/core/compile/sqlglot/scalar_compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
from bigframes.core.compile.sqlglot.expressions.typed_expr import TypedExpr
import bigframes.core.compile.sqlglot.sqlglot_ir as ir
import bigframes.core.expression as ex
from bigframes.operations import numeric_ops
import bigframes.operations as ops


Expand Down Expand Up @@ -180,3 +181,15 @@ def _register(

# Singleton compiler
scalar_op_compiler = ScalarOpCompiler()


@scalar_op_compiler.register_unary_op(numeric_ops.isnanornull_op)
def isnanornull(arg: TypedExpr) -> sge.Expression:
return sge.Or(this=sge.IsNan(this=arg.expr), right=sge.IsNull(this=arg.expr))


@scalar_op_compiler.register_unary_op(numeric_ops.isfinite_op)
def isfinite(arg: TypedExpr) -> sge.Expression:
return sge.Not(
this=sge.Or(this=sge.IsInf(this=arg.expr), right=sge.IsNan(this=arg.expr))
)
16 changes: 16 additions & 0 deletions bigframes/operations/numeric_ops.py
Original file line number Diff line number Diff line change
Expand Up @@ -348,3 +348,19 @@ def output_type(self, *input_types: dtypes.ExpressionType) -> dtypes.ExpressionT
name="unsafe_pow_op", type_signature=op_typing.BINARY_REAL_NUMERIC
)
unsafe_pow_op = UnsafePowOp()

IsNanOrNullOp = base_ops.create_unary_op(
name="isnanornull",
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

name?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done in 7f1bca4, thanks.

type_signature=op_typing.FixedOutputType(
dtypes.is_numeric, dtypes.BOOL_DTYPE, "numeric"
),
)
isnanornull_op = IsNanOrNullOp()

IsFiniteOp = base_ops.create_unary_op(
name="isfinite",
type_signature=op_typing.FixedOutputType(
dtypes.is_numeric, dtypes.BOOL_DTYPE, "numeric"
),
)
isfinite_op = IsFiniteOp()
2 changes: 2 additions & 0 deletions bigframes/operations/numpy_op_maps.py
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@
np.ceil: numeric_ops.ceil_op,
np.log1p: numeric_ops.log1p_op,
np.expm1: numeric_ops.expm1_op,
np.isnan: numeric_ops.isnanornull_op,
np.isfinite: numeric_ops.isfinite_op,
}


Expand Down
2 changes: 2 additions & 0 deletions tests/system/small/test_numpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
("log10",),
("sqrt",),
("abs",),
("isnan",),
("isfinite",),
],
)
def test_series_ufuncs(floats_pd, floats_bf, opname):
Expand Down
Loading