Thanks to visit codestin.com
Credit goes to github.com

Skip to content

np.repeat not accepting np.uint for repeats #15965

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
jeras opened this issue Apr 13, 2020 · 4 comments
Open

np.repeat not accepting np.uint for repeats #15965

jeras opened this issue Apr 13, 2020 · 4 comments

Comments

@jeras
Copy link

jeras commented Apr 13, 2020

Repeat only accepts int or int array for repeats, np.uint is not accepted. But the function still checks if repeats are negative. I am working with nonegative values this becomes an unnecessary conversion step.

Reproducing code example:

import numpy as np
x = np.array([1,2,3,4])
r = np.array([1,0,0,2], dtype=np.uint)
x.repeat(r)

Error message:

---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-2-9ac14301bd8a> in <module>
      2 x = np.array([1,2,3,4])
      3 r = np.array([1,0,0,2], dtype=np.uint)
----> 4 x.repeat(r)

TypeError: Cannot cast array data from dtype('uint64') to dtype('int64') according to the rule 'safe'

Numpy/Python version information:

1.17.4 3.8.2 (default, Mar 13 2020, 10:14:16) 
[GCC 9.3.0]
@eric-wieser
Copy link
Member

I think this is by design, things like indices / strides / repeat numbers are expected to be of type intp, and anything else is cast. In this case, the casting is "safe", meaning it refuses to cast uint64 to int64 as it would corrupt values >= 2**63.

Performing the cast yourself with a less strict casting rule (such as .astype(np.intp)) would solve your issue, while performing the same number of casts.

@jeras
Copy link
Author

jeras commented Apr 13, 2020

I can't comment on Python/Numpy design preferences, I just thought uint could be used for repeats, this would have to bypass the check for negative values, and there would be no need for casting, since uint64 is already the same (on many architectures) as the uintptr_t from stdint.h.

I already used .astype(np.int) for casting and I will consider using 'intp`.

Feel free to close this issue.

@eric-wieser
Copy link
Member

You should never use np.int, as it's just a really bad spelling of int (#6103). If you mean the C long type, use np.int_ (which is the complement to np.uint, the C unsigned long type).

Internally, numpy has chosen to use intptr_t (np.intp) almost everywhere, staying away from uintptr_t (np.uintp). This is partially motivated by the need for negative strides, but probably mostly just for simplicity.

I don't want to close this issue just yet, I agree your use-case is fairly reasonable.

this would have to bypass the check for negative values

Right, but you wouldn't actually get an efficiency gain here because instead we'd need to perform a check that all values are less than 2**63 before casting internally to intp.

@seberg
Copy link
Member

seberg commented Apr 13, 2020

In most of these places we do use same kind casting. That is arguably incorrect of course, but unfortunately not being able to index e.g. with a uint64 would be strange as well. The only fix would be to have a whole code path(s) around bounds-checking for different integer types.

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

No branches or pull requests

3 participants