8000 BUG: `astype(copy=False)` and `asarray` deep-copy the buffer when changing signedness · Issue #27509 · numpy/numpy · GitHub
[go: up one dir, main page]

Skip to content

BUG: astype(copy=False) and asarray deep-copy the buffer when changing signedness #27509

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
crusaderky opened this issue Oct 5, 2024 · 4 comments
Labels

Comments

@crusaderky
Copy link
Contributor

Describe the issue:

When ndarray.astype(..., copy=False) converts between two dtypes with same word size that exclusively differ in signedness, it deep-copies the buffer but there's no reason for it to do so, as the two formats exclusively differ by the meaning attributed to the most-significant bit.

This issue also affects np.asarray(..., dtype=...) which I presume internally calls ndarray.astype(..., copy=False).

Expected behaviour

An array with dtype=uintX could and should be a view of another array with dtype=intX, and vice versa.

Related

Reproduce the code example:

>>> a = np.array([1, -1], dtype='i2')
>>> b = a.astype('u2', copy=False)
>>> b
array([    1, 65535], dtype=uint16)
>>> b.base
(None)

Error message:

No response

Python and NumPy Versions:

python 3.12, numpy 2.1.1,

Runtime Environment:

conda linux x86_64

Context for the issue:

No response

@jakevdp
Copy link
Contributor
jakevdp commented Oct 5, 2024

Thanks for the report! I believe this is working as intended: astype in general forces a copy when converting between different dtypes. It sounds like what you're looking for is ndarray.view, which will change the dtype without copying the buffer:

import numpy as np
x = np.arange(4, dtype='int64')
x2 = x.view('uint64')

@mhvk
Copy link
Contributor
mhvk commented Oct 5, 2024

Just to add to @jakevdp's com B1C2 ment - astype is documented as returning either a copy or the original array, so to return a view for copy=False would be unexpected.
You are correct, though, that it is not unreasonable to create a view for the examples you give, as the actual bytes in the array are identical. In principle, one could think of changing the behaviour of .astype(..., copy=False), but my sense is that it is not quite worth it, as I think it is pretty uncommon.

@seberg
Copy link
Member
seberg commented Oct 6, 2024

We have the ability to implement a cast as "just a view" now. But we didn't do that here to not change behavior (astype doesn't matter, but asarray(, dtype=) or other paths need at least some thought).
So not sure it is worth it either, although there are probably some paths (indexing with unsigned) where it might save a bit.

@crusaderky
Copy link
Contributor Author

xref data-apis/array-api#867

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

4 participants
0