Skip to content

[SPARK-58582][PS] Use native Spark function for NumPy fmod - #57784

Closed
zhengruifeng wants to merge 12 commits into
apache:masterfrom
zhengruifeng:pandas-native-fmod-dev2
Closed

[SPARK-58582][PS] Use native Spark function for NumPy fmod#57784
zhengruifeng wants to merge 12 commits into
apache:masterfrom
zhengruifeng:pandas-native-fmod-dev2

Conversation

@zhengruifeng

Copy link
Copy Markdown
Contributor

What changes were proposed in this pull request?

Replaces the pandas UDF used for np.fmod in the pandas API on Spark with Spark’s native remainder expression.

Adds coverage for integral and floating inputs, including zero divisors, infinities, and NaN.

Why are the changes needed?

Using native Spark expressions avoids pandas UDF serialization and lets Spark optimize and code-generate this operation while preserving NumPy-compatible behavior.

Does this PR introduce any user-facing change?

No. This is a behavior-preserving implementation change.

How was this patch tested?

source ~/.zshrc && conda run -n spark-dev-313 python/run-tests --testnames pyspark.pandas.tests.test_numpy_compat.NumPyCompatTests.test_np_fmod

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

Generated-by: Codex (GPT-5)

Comment thread python/pyspark/pandas/numpy_compat.py Outdated
.cast("double"),
"fmin": lambda c1, c2: F.least(c1, c2).cast("double"),
"fmod": pandas_udf(lambda s1, s2: np.fmod(s1, s2), DoubleType()), # type: ignore[call-overload]
"fmod": lambda c1, c2: F.when(

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

When c2 is NULL and c1 is non-null, the outer when(c1.isNull() | c2.isNull(), c1.cast("double")) returns the dividend's value rather than NULL. Under the old pandas-udf, Spark NULL was converted to pandas NaN before calling np.fmod, so np.fmod(x, NaN) = NaN; the null-divisor propagated as NaN. The new code returns c1 unchanged for a null divisor. In practice, float columns in pandas-on-Spark use NaN (not NULL) for missing values, so the practically-affected population is nullable-integer columns with Python None entries (e.g. pd.array([1, 2, None], dtype="Int64")); those are fully supported and the divergence is reachable. Fix: the outer NULL clause is superfluous — (c1 % c2) already propagates NULL through Spark's built-in null semantics in both positions; removing the outer when clause entirely is cleaner and fixes the regression.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Addressed in ebdec05. Removed the incorrect null branch; the zero-divisor case now also requires a non-null dividend, so native remainder propagates nulls. Added nullable Int64 coverage, and the focused test passes.

zhengruifeng added a commit that referenced this pull request Aug 6, 2026
### What changes were proposed in this pull request?

Replaces the pandas UDF used for `np.fmod` in the pandas API on Spark with Spark’s native remainder expression.

Adds coverage for integral and floating inputs, including zero divisors, infinities, and NaN.

### Why are the changes needed?

Using native Spark expressions avoids pandas UDF serialization and lets Spark optimize and code-generate this operation while preserving NumPy-compatible behavior.

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

No. This is a behavior-preserving implementation change.

### How was this patch tested?

`source ~/.zshrc && conda run -n spark-dev-313 python/run-tests --testnames pyspark.pandas.tests.test_numpy_compat.NumPyCompatTests.test_np_fmod`

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

Generated-by: Codex (GPT-5)

Closes #57784 from zhengruifeng/pandas-native-fmod-dev2.

Authored-by: Ruifeng Zheng <ruifengz@apache.org>
Signed-off-by: Ruifeng Zheng <ruifengz@apache.org>
(cherry picked from commit 6ef2cdb)
Signed-off-by: Ruifeng Zheng <ruifengz@apache.org>
@zhengruifeng

Copy link
Copy Markdown
Contributor Author

Merge Summary:

Posted by merge_spark_pr.py

@zhengruifeng
zhengruifeng deleted the pandas-native-fmod-dev2 branch August 6, 2026 11:23
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.

3 participants