Numpy floor float values to int

Viewed 4879

I have array of floats, and I want to floor them to nearest integer, so I can use them as indices.

For example:

In [2]: import numpy as np

In [3]: arr = np.random.rand(1, 10) * 10

In [4]: arr
Out[4]:
array([[4.97896461, 0.21473121, 0.13323678, 3.40534157, 5.08995577,
        6.7924586 , 1.82584208, 6.73890807, 2.45590354, 9.85600841]])

In [5]: arr = np.floor(arr)

In [6]: arr
Out[6]: array([[4., 0., 0., 3., 5., 6., 1., 6., 2., 9.]])

In [7]: arr.dtype
Out[7]: dtype('float64')

They are still floats after flooring, is there a way to automatically cast them to integers?

3 Answers

I am edit answer with @DanielF explanation: "floor doesn't convert to integer, it just gives integer-valued floats, so you still need an astype to change to int" Check this code to understand the solution:

import numpy as np
arr = np.random.rand(1, 10) * 10
print(arr)
arr = np.floor(arr).astype(int)
print(arr)
OUTPUT:
[[2.76753828 8.84095843 2.5537759  5.65017407 7.77493733 6.47403036
  7.72582766 5.03525625 9.75819442 9.10578944]]
[[2 8 2 5 7 6 7 5 9 9]]

Why not just use:

np.random.randint(1,10)

As alternative to changing type after floor division, you can provide an output array of the desired data type to np.floor (and to any other numpy ufunc). For example, imagine you want to convert the output to np.int32, then do the following:

import numpy as np
arr = np.random.rand(1, 10) * 10
out = np.empty_like(arr, dtype=np.int32)
np.floor(arr, out=out, casting='unsafe')

As the casting argument already indicates, you should know what you are doing when casting outputs into different types. However, in your case it is not really unsafe.

Although, I would not call np.floor in your case, because all values are greater than zero. Therefore, the simplest and probably fastest solution to your problem would be a direct casting to integer.

import numpy as np
arr = (np.random.rand(1, 10) * 10).astype(int)
Related