Repository navigation
Keep the float dtype in mean(), as NumPy does - #755
Open
FabianIsensee wants to merge 1 commit into
Open
FabianIsensee wants to merge 1 commit into
FabianIsensee wants to merge 1 commit into
Conversation
mean() divides the sum by the count, and that division can promote a float32 (or complex64) result to float64: - With NumPy 1.x, a float32 scalar divided by a Python int becomes float64 (value-based casting), so every full a.mean() of float32 returned float64; so did axis reductions over more than 65535 elements (an array over such an int). - With where=, the count is an int64 sum, so a.mean(where=...) of float32 returned float64 with any NumPy. complex64 with where= came back complex128 as well, because the sum of its where() already was. NumPy returns the input's float dtype (or a floating dtype=). The quotient is now cast to that dtype; integer and bool inputs keep their float64 mean. std() and var() take their mean from here too. Test: test_mean_dtype_matches_numpy (float32/float64/complex64/int32/ bool, axis, keepdims, where) has 16 of 40 cases failing without this on NumPy 1.26, and 8 on NumPy 2.5. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hi Francesc,
a small fix I found while looking into #752's NumPy 1.26 CI job. It is one commit on top of
main(d240a49), independent of my other PRs.improved-miniexprhas the samemean(), so it applies there too.Why:
mean()of float32 data can return float64.mean()divides the sum by the count, and that division promotes the dtype:a.mean()of float32 returns float64, and so do axis reductions over more than 65535 elements.where=, the count is an int64 sum, soa.mean(where=mask)of float32 returns float64 with any NumPy. complex64 withwhere=comes back as complex128.NumPy returns float32 (complex64) in all these cases.
What: the quotient is cast to NumPy's dtype: the input's float dtype, or a floating
dtype=. Integer and bool inputs keep their float64 mean.std()andvar()take their mean from here, so they also stay float32 withddof=0. Withddof != 0, the rescaling byn / (n - ddof)onmainstill makes them float64 in these cases; #752 fixes that onimproved-miniexpr.Tests:
test_mean_dtype_matches_numpy(float32/float64/complex64/int32/bool, axis, keepdims,where). Without the fix, 16 of its 40 cases fail on NumPy 1.26 and 8 on NumPy 2.5.pytest testswith NumPy 2.5: 9485 passed. The 2 failures are theb2viewhttp tests that need aiohttp, as onmain. With NumPy 1.26, the only difference frommainis the new test.AI disclosure: the analysis, fix and test were done with Claude Code; I reviewed them.
Best,
Fabian
🤖 Generated with Claude Code