29

Is there any built in function to discard integer and keep only float number in numpy.

import numpy as np

input = np.array([0.0, 0.01, 1.0, 2.0, 2.001, 2.002])

desired_ouput = some_function(input)
# Expected ouput
# desired_output = np.array([0.01, 2.001, 2.002])
1
  • 5
    All values in that array are floats. "float" doesn't imply anything about the value being non-integer. Commented Aug 30, 2018 at 19:00

7 Answers 7

18

Mask with whether each element is equal to it as an integer.

arr = np.array([0.0, 0.01, 1.0, 2.0, 2.001, 2.002])
out = arr[arr != arr.astype(int)]
#np.array([0.01, 2.001, 2.002])
Sign up to request clarification or add additional context in comments.

Comments

18

I don't think so. My approach would be

import numpy as np
a = np.array([0.0, 0.01, 1.0, 2.0, 2.001, 2.002])
mask = np.isclose(a, a.astype(int))

print(a[~mask])
#[ 0.01   2.001  2.002]

2 Comments

As a general rule always use isclose when comparing floats. I'm not sure it's necessary here, but upvoted for good practice.
It's not a good practice to blindly follow what is called "good practice". isclose, depending on the source of these numbers, may actually be actively harmful.
6

I know of no in-built function. But you can create one yourself:

import numpy as np

A = np.array([0.0, 0.01, 1.0, 2.0, 2.001, 2.002])

def remove_ints(arr):
    return arr[~(arr == arr.astype(int))]

res = remove_ints(A)

array([ 0.01 ,  2.001,  2.002])

Aside, you should not use a built-in class such as input as a variable name.

Comments

6

I've always used np.equal with np.mod:

>>> A[~np.equal(np.mod(A, 1), 0)]
array([0.01 , 2.001, 2.002])

Comments

4

If you do not have to much data (short list), maybe do not need numpy:

>>> i = [0.0, 0.01, 1.0, 2.0, 2.001, 2.002]
>>> a=[j for j in i if not j.is_integer()]
>>> a
['0.01', '2.001', '2.002']

Otherwise see Joe Iddon answer

1 Comment

The idea of scipy is to never use for for efficiency.
2

I don't know any builtin for this but you can filter those floats using:

filter(lambda x: int(str(x).split('.')[1]) != 0, input)

The lambda expression here checks if the decimal places are zero which I interpret as the number being an int.

4 Comments

precision is lost by converting to string. e.g 2.001 becomes 2.0009999999999999.
What? I just tried replicating this but [str(x) for x in input] returned: ['0.0', '0.01', '1.0', '2.0', '2.001', '2.002']? But even if i assume a loss of accuracy, it wouldn't change the results since '001' will not come out as 0 after the int cast, just like '00099999'.
It happend in my python. Actually these are indexes of pandas dataframe, so loss of precision mean, i can't get back values by apply .loc method.
Well, this would be very interesting indeed if you can find a way to replicate the effect...
0

I had a similar question a while back: Numpy: Check if float array contains whole numbers. The simplest way to mask fractions that I am currently aware of is

mask = ((input % 1) != 0)

You can then apply the mask directly with

output = input[mask]

It bothered me that there is no built-in function to determine the integerness of a float quickly, so I wrote a fast ufunc that provides the functionality of float.is_integer for numpy. You can download from github and compile if you're interested:

from is_integer_ufunc import is_integer

output = input[~is_integer(input)]

I'll see if the numpy community wants to consider adding something like that to the core library. The question seems to come up often enough to justify it.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.