Skip to content

Commit 07e677b

Browse files
feat: Implement isnan and isfinite in bigframes
This commit implements the `isnan` and `isfinite` numpy ufuncs in bigframes. The following changes were made: - Added `IsNanOrNullOp` and `IsFiniteOp` to `bigframes/operations/numeric_ops.py` - Mapped `np.isnan` and `np.isfinite` to the new ops in `bigframes/operations/numpy_op_maps.py` - Added compilation logic for the new ops to the ibis, polars, and sqlglot compilers - Added tests for the new ops in `tests/system/small/test_numpy.py` - Renamed `IsNanOp` to `IsNanOrNullOp` to match numpy semantics and updated compilers accordingly.
1 parent 2f13311 commit 07e677b

File tree

5 files changed

+14
-16
lines changed

5 files changed

+14
-16
lines changed

bigframes/core/compile/ibis_compiler/scalar_op_compiler.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -270,9 +270,9 @@ def _convert_range_ordering_to_table_value(
270270
scalar_op_compiler = ExpressionCompiler()
271271

272272

273-
@scalar_op_compiler.register_unary_op(numeric_ops.isnan_op)
274-
def isnan(arg):
275-
return arg.isnan()
273+
@scalar_op_compiler.register_unary_op(numeric_ops.isnanornull_op)
274+
def isnanornull(arg):
275+
return arg.isnan() | arg.isnull()
276276

277277

278278
@scalar_op_compiler.register_unary_op(numeric_ops.isfinite_op)

bigframes/core/compile/polars/compiler.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -199,9 +199,9 @@ def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
199199
def _(self, op: ops.ScalarOp, input: pl.Expr) -> pl.Expr:
200200
return input.ceil()
201201

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

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

bigframes/core/compile/sqlglot/scalar_compiler.py

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@
2121
from bigframes.core.compile.sqlglot.expressions.typed_expr import TypedExpr
2222
import bigframes.core.compile.sqlglot.sqlglot_ir as ir
2323
import bigframes.core.expression as ex
24-
from bigframes.operations import numeric_ops
2524
import bigframes.operations as ops
25+
from bigframes.operations import numeric_ops
2626

2727

2828
class ScalarOpCompiler:
@@ -183,13 +183,11 @@ def _register(
183183
scalar_op_compiler = ScalarOpCompiler()
184184

185185

186-
@scalar_op_compiler.register_unary_op(numeric_ops.isnan_op)
187-
def isnan(arg: TypedExpr) -> sge.Expression:
188-
return sge.IsNan(this=arg.expr)
186+
@scalar_op_compiler.register_unary_op(numeric_ops.isnanornull_op)
187+
def isnanornull(arg: TypedExpr) -> sge.Expression:
188+
return sge.Or(this=sge.IsNan(this=arg.expr), right=sge.IsNull(this=arg.expr))
189189

190190

191191
@scalar_op_compiler.register_unary_op(numeric_ops.isfinite_op)
192192
def isfinite(arg: TypedExpr) -> sge.Expression:
193-
return sge.Not(
194-
this=sge.Or(this=sge.IsInf(this=arg.expr), right=sge.IsNan(this=arg.expr))
195-
)
193+
return sge.Not(this=sge.Or(this=sge.IsInf(this=arg.expr), right=sge.IsNan(this=arg.expr)))

bigframes/operations/numeric_ops.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -349,13 +349,13 @@ def output_type(self, *input_types: dtypes.ExpressionType) -> dtypes.ExpressionT
349349
)
350350
unsafe_pow_op = UnsafePowOp()
351351

352-
IsNanOp = base_ops.create_unary_op(
353-
name="isnan",
352+
IsNanOrNullOp = base_ops.create_unary_op(
353+
name="isnanornull",
354354
type_signature=op_typing.FixedOutputType(
355355
dtypes.is_numeric, dtypes.BOOL_DTYPE, "numeric"
356356
),
357357
)
358-
isnan_op = IsNanOp()
358+
isnanornull_op = IsNanOrNullOp()
359359

360360
IsFiniteOp = base_ops.create_unary_op(
361361
name="isfinite",

bigframes/operations/numpy_op_maps.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
np.ceil: numeric_ops.ceil_op,
4141
np.log1p: numeric_ops.log1p_op,
4242
np.expm1: numeric_ops.expm1_op,
43-
np.isnan: numeric_ops.isnan_op,
43+
np.isnan: numeric_ops.isnanornull_op,
4444
np.isfinite: numeric_ops.isfinite_op,
4545
}
4646

0 commit comments

Comments
 (0)