Skip to content

[SPARK-59232][PS] Support boolean operands in NumPy ufuncs - #58509

Closed
Spenserrrr wants to merge 1 commit into
apache:masterfrom
Spenserrrr:numpy-ufunc-boolean-cast
Closed

[SPARK-59232][PS] Support boolean operands in NumPy ufuncs#58509
Spenserrrr wants to merge 1 commit into
apache:masterfrom
Spenserrrr:numpy-ufunc-boolean-cast

Conversation

@Spenserrrr

@Spenserrrr Spenserrrr commented Sep 4, 2026

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

maybe_dispatch_ufunc_to_spark_func now casts a boolean operand to tinyint before building the expression, the way NumPy promotes one to int8 before it picks a loop. np.invert and np.negative reuse the existing logical_not mapping instead, since NumPy reads a boolean logically for those two.

Why are the changes needed?

Most ufuncs in the mapping tables raise AnalysisException on a boolean column, because Spark's functions have no implicit boolean-to-numeric cast, where pandas returns a value: np.sqrt(ps.Series([True, False])) fails while pandas answers [1.0, 0.0]. The accepted-type table added in #58485 already lists BooleanType for these ufuncs, so the failure contradicts it.

Does this PR introduce any user-facing change?

Yes. A NumPy ufunc on a boolean column now returns a value instead of raising; the values match pandas, while the result dtype follows Spark's math functions, which return double.

How was this patch tested?

New test_np_boolean_operand and test_np_boolean_operand_logical in NumPyCompatTestsMixin, both of which fail without the change.

Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 5)

Cast a boolean operand to tinyint before building the ufunc expression, as
NumPy promotes one to int8 before choosing a loop. np.invert and np.negative
reuse the existing logical_not mapping instead, since NumPy reads a boolean
logically for those two.
@Spenserrrr
Spenserrrr marked this pull request as ready for review September 4, 2026 00:54
@Spenserrrr

Copy link
Copy Markdown
Contributor Author

Hi @zhengruifeng! This is a follow-up PR mentioned in #58485, which left boolean operands accepted by the type table but still failing at analysis. Could you take a look when you have time? Thanks!

zhengruifeng pushed a commit that referenced this pull request Sep 4, 2026
### What changes were proposed in this pull request?

`maybe_dispatch_ufunc_to_spark_func` now casts a boolean operand to `tinyint` before building the expression, the way NumPy promotes one to `int8` before it picks a loop. `np.invert` and `np.negative` reuse the existing `logical_not` mapping instead, since NumPy reads a boolean logically for those two.

### Why are the changes needed?

Most ufuncs in the mapping tables raise `AnalysisException` on a boolean column, because Spark's functions have no implicit boolean-to-numeric cast, where pandas returns a value: `np.sqrt(ps.Series([True, False]))` fails while pandas answers `[1.0, 0.0]`. The accepted-type table added in #58485 already lists `BooleanType` for these ufuncs, so the failure contradicts it.

### Does this PR introduce _any_ user-facing change?

Yes. A NumPy ufunc on a boolean column now returns a value instead of raising; the values match pandas, while the result dtype follows Spark's math functions, which return double.

### How was this patch tested?

New `test_np_boolean_operand` and `test_np_boolean_operand_logical` in `NumPyCompatTestsMixin`, both of which fail without the change.

### Was this patch authored or co-authored using generative AI tooling?

Generated-by: Claude Code (Claude Opus 5)

Closes #58509 from Spenserrrr/numpy-ufunc-boolean-cast.

Authored-by: Spenser Sun <hsun112358@gmail.com>
Signed-off-by: Ruifeng Zheng <ruifengz@foxmail.com>
(cherry picked from commit d0bc986)
Signed-off-by: Ruifeng Zheng <ruifengz@foxmail.com>
@zhengruifeng

Copy link
Copy Markdown
Contributor

Merge Summary:

Posted by merge_spark_pr.py

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants